CURL


/**
 * curl例子  
 * @param $query
 * [
 *  'url'=>'www.baidu.com', //链接
 *  'timeput'=>30,          //超时时间 秒
 *  'headers'=>''          //请求头信息
 *  'postData'=>''         //请求数据
 *  'proxy'=>'127.0.0.1:8888' //代理
 * ]
 */
function curlSetting($query)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $query['url']); // 设置url
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回请求结果,不直接输出
    curl_setopt($ch, CURLOPT_HEADER, true); // 请求结果中也要包含响应的heade0r
    // 设置超时
    $timeout = isset($query['timeout']) ?: 30;
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 允许跳转
    curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024);

//        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
//        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

    // 设置请求HEADER
    if (isset($query['headers'])) {
        if (!isAssocArray($query['headers'])) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $query['headers']);
        } else {
            $headers = [];
            foreach ($query['headers'] as $k => $v) $headers[] = "{$k}: {$v}";
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }
    }

    // 设置post及其数据
    if (isset($query['postData']) && !is_null($query['postData'])) {
        curl_setopt($ch, CURLOPT_POST, true);
        if (is_string($query['postData'])) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, $query['postData']);
        } elseif (is_array($query['postData'])) {
            $queryString = http_build_query($query['postData']);
            // 有可能出现为应对 hobbies[]=swimming&hobbies[]=football 这种情况而出现的 hobbies[0]=swimming&hobbies[1]=football
            $queryString = preg_replace('/%5B\d+%5D/simU', '%5B%5D', $queryString);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $queryString);
        }
    }

    // 设置代理
    !empty($query['proxy']) && curl_setopt($ch, CURLOPT_PROXY, $query['proxy']);
    $response = curl_exec($ch);
    $curlInfo = curl_getinfo($ch);
    var_dump($curlInfo);

}

curlMulti

// 多线程抓取
class CurlMulti
{
    protected static $mh = null;

    // task中需要包含url header postdata proxy timeout
    public static function send(array $tasks)
    {
        // 添加任务到并行句柄中
        foreach ($tasks as $task) {
            $ch = self::taskSetting($task['url'], $task['headers'], $task['post_data'], $task['proxy'], $task['timeout']);
            curl_multi_add_handle(self::getMh(), $ch);
        }

        $result = [];
        do {
            curl_multi_exec(self::getMh(), $running);

            if (($info = curl_multi_info_read(self::getMh())) !== false) {
                if ($info['result'] === CURLE_OK) {
                    $curlInfo     = curl_getinfo($info['handle']);
                    $response     = curl_multi_getcontent($info['handle']);
                    $body         = substr($response, - $curlInfo['size_download']);
                    $header     = substr($response, 0, strlen($response) - $curlInfo['size_download']);
                    $taskCur    = $tasks[array_search($curlInfo['url'], array_column($tasks, 'url'))];
                    if (!empty($taskCur['callback'])) $body = call_user_func_array($taskCur['callback'], [$body]);
                    $result[]     = [
                        'code'         => $curlInfo['http_code'],
                        'header'    => $header,
                        'body'        => empty($taskCur['callback']) ? $body : call_user_func_array($taskCur['callback'], [$body]),
                        'curlInfo'     => $curlInfo,
                    ];
                }
                curl_close($info['handle']);
                curl_multi_remove_handle(self::getMh(), $info['handle']);
            }

        } while ($running > 0);

        return $result;
    }

    protected static function taskSetting($url, $headers = [], $postData = null, $proxy = '', $timeout = 30)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        !empty($headers) && curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        if (!is_null($postData)) {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        }
        if (!empty($proxy)) curl_setopt($ch, CURLOPT_PROXY, $proxy);
        return $ch;
    }

    protected static function getMh()
    {
        if (is_null(self::$mh)) {
            self::$mh = curl_multi_init();
        }
        return self::$mh;
    }
}

算法时间复杂度的表示法O(n²)、O(n)、O(1)、O(nlogn)

简单理解: 就是变量为n的时候,算法需要对变量操作次数的量级。
简单解释:
简单说O(n²)表示当n很大的时候,复杂度约等于Cn²,C是某个常数,简单说就是当n足够大的时候,n的线性增长,复杂度将沿平方增长。
O(n)也是差不多的意思,也就是说n很大的时候复杂度约等于Cn,C是某个常数。
O(1)就是说n很大的时候,复杂度基本就不增长了,基本就是个常量C。
举例解释:
要找到一个数组里面最大的一个数,你要把n个变量都扫描一遍,操作次数为n,那么算法复杂度是O(n).
用冒泡排序排一个数组,对于n个变量的数组,需要交换变量位置n^2 次,那么算法复杂度就是O(n^2 ).
有时候,如果对变量操作的次数是个多项式比如n^4+n^2+n, 就取数量级最大的那个,O(n^4)clipboard.png

clipboard.png

下载地址 https://github.com/weiyixi/PhpMail-SMTP-POP3-IMAP

PhpMail-SMTP-POP3-IMAP 邮件接收发送 Mail receiving and sending

最近遇到一个工程需要自动发件(SMTP)收件(IMAP/POP3)功能,发现很难找到一个PHP的完整包来使用
所以自己综合phpMailer,PhpImap,csdn博客等各开源代码,做一个收发件都包括的库,供新人使用。
有不足之处请指出

imap 收件示例

require_once __DIR__ . '/src/__autoload.php';
set_time_limit(0);
//IMAP收件
//argument is the directory into which attachments are to be saved:
$mailbox = new \src\PhpImap\Mailbox('{imap.qq.com:993/imap/ssl}INBOX', 'XXXXXXX@qq.com', 'XXXXXXX', __DIR__);
//读取所有邮件id到数组:
//Read all messaged into an array:
$mailsIds = $mailbox->searchMailbox('ALL');
if (!$mailsIds) {
    die('Mailbox is empty');
}
// Get the first message and save its attachment(s) to disk:
//获取一份邮件对象 打印出来
$mail = $mailbox->getMail($mailsIds[0]);
var_dump($mail);
die;

pop3 收件示例

require_once __DIR__ . '/src/__autoload.php';
set_time_limit(0);

$host = "tls://pop.126.com"; //‘tls://’为ssl协议加密,端口走加密端口
$user = "XXXXXX@126.com"; //邮箱
$pass = "XXXXXX"; //密码
$rec = new \src\pop3\Pop3($host, 995, 3);
//打开连接
if (!$rec->open())
    die($rec->err_str);
echo "open ";
//登录
if (!$rec->login($user, $pass)) {
    var_dump($rec->err_str);
    die;
}
echo "login";

if (!$rec->stat())
    die($rec->err_str);
echo "You  have" . $rec->messages . "emails,total size:" . $rec->size . "<br>";
if ($rec->messages > 0) {
    //读取邮件列表
    if (!$rec->listmail())
        die($rec->err_str);
    echo "Your mail list:<br>";
    for ($i = 1; $i <= count($rec->mail_list); $i++) {
        echo "mailId:" . $rec->mail_list[$i]['num'] . "Size:" . $rec->mail_list[$i]['size'] . "<BR>";
    }
    //获取一个邮件
    //read One email
    $rec->getmail(1);
    echo "getHeader:<br>";
    for ($i = 0; $i < count($rec->head); $i++) {
        echo htmlspecialchars($rec->head[$i]) . "<br>\n";
    }

    echo "getContent:<BR>";
    for ($i = 0; $i < count($rec->body); $i++) {
        echo htmlspecialchars($rec->body[$i]) . "<br>\n";
    }
}
$rec->close();

die;

SMTP 发件

require_once __DIR__ . '/src/__autoload.php';
set_time_limit(0);

/**
 * @param $sendto_email  收件地址
 * @param $sendto_name   收件人
 * @param $subject       邮件标题
 * @param $body          邮件内容
 * @param $user_name     送件人
 * @param $post_array =[
 *          'server_address'=>'smtp.qq.com',    //smtp  服务器
 *          'port'=>465,                        //端口
 *          'mail_id'=>'AAAA@qq.com',          //账号
 *          'mail_pwd'=>'密码',                   //密码
 *          'mail_address'=>'发件人邮箱'
 * ]
 * @return bool
 * @throws \src\PHPMailer\Exception
 */
var_dump(smtp_mail('XXXXXX@qq.com', 'XXXX', 'hahah', 'aaaaaa', 'XXX', [
    'server_address' => 'smtp.126.com',    //smtp  服务器
    'port' => 465,                        //端口
    'mail_id' => 'XXXXX@126.com',          //账号
    'mail_pwd' => 'XXXXX',                   //密码
    'mail_address' => 'XXXXXX@126.com'
]));
function smtp_mail($sendto_email, $sendto_name, $subject, $body, $user_name, $post_array,$is_html=false)
{
    $mail = new \src\PHPMailer\PHPMailer();
    $mail->SMTPDebug = 0;   // 开启Debug
    $mail->IsSMTP();                // 使用SMTP模式发送新建
    $mail->Host = $post_array['server_address']; // QQ企业邮箱SMTP服务器地址
    $mail->Port = $post_array['port'];  //邮件发送端口,一定是465
    $mail->SMTPAuth = true;         // 打开SMTP认证,本地搭建的也许不会需要这个参数
    $mail->SMTPSecure = "ssl";  // 打开SSL加密,这一句一定要
    $mail->Username = $post_array['mail_id'];   // SMTP用户名
    $mail->Password = $post_array['mail_pwd'];        // 为QQ邮箱SMTP的独立密码,即授权码
    $mail->From = $post_array['mail_address'];      // 发件人邮箱
    $mail->FromName = $user_name;// $post_array['mail_address'];  // 发件人

    $mail->CharSet = "UTF-8";            // 这里指定字符集!
    $mail->Encoding = "base64";
    if (!$mail->AddAddress($sendto_email, $sendto_name)) {
        return false;
    }  // 收件人邮箱和姓名
    $mail->addCC($post_array['mail_address']);//抄送
    $mail->IsHTML($is_html);  // send as HTML
    // 邮件主题
    $mail->Subject = $subject;

    $mail->Body = $body;      //isHTML是true 的时候  这里body有效
    $mail->AltBody = str_replace("<br/>", "\r\n", $body);  //isHTML是false 的时候  这里body有效
    if (!$mail->Send()) {
        return false;
    } else {
        return true;
    }
}

前方高能来袭,这是一套成熟的通过三次约会套路到男神的方法论-三板斧约会法,可能有点婊里婊气,但是实测非常好用,请分享给你身边需要它的姑娘们(手动滑稽)。

【三板斧起手】——诱导邀约

男生约女生,强调不要怂主动出击。

而女生约男生太过主动不合适,所以我们要诱导男生进行流程,让他以为这一切都是“他想做”。

所以我们和男生聊天互动时,要对男生呈现分享的话题表示出极大的兴趣,引导男生和我们多聊天。

举个例子:

“我一直都想试试打篮球呢,过去学校里一直没人教我,自己也不知道怎么开始学,没想到你打篮球这么厉害,好羡慕你。”

“哈哈哈说起来你可能不信,我一直看你们男生打LOL,渐渐的开始感兴趣了,想找一个机会尝试一下呢。”

“嗯嗯我也觉得我需要考一下研究生,不过基础不太好,数学方面一直很弱,所以蛮崇拜你这种能把高数线代玩的转的学霸。”

这个时候,情商高一点的男生都会顺水推舟说“那我教你吧”,这时候你们接触的机会就有了。

不过我们实在不能对直男的情商抱多大希望,所以如果他这个时候直接给你甩了一堆教程安利了一堆书或者教学视频,也是有可能出现的。

来,喝口水,压压飙升的血压,开始卖萌撒个娇:“好多东西啊……我怕没人讲我听不会,你能当下我师傅嘛?请你吃好吃哒。”

同样的道理,我们约男生时最好不要说:“最近新上映了一部电影,我们要不要去看看。”

你要说:

“最近有什么安排嘛……唉说起这个我就郁闷,最近新上映了一部电影,本来说好和闺蜜一起去的,结果她抛弃我去找男朋友了,就剩下我一个人了,好想去看啊,但是感觉一个人去看电影好尴尬。”

有的女生就坐不住了:这不就是传说中装诱惑的绿茶吗?这不就是卖萌示弱勾引男生的心机girl吗?

你是想泡男生的,学着点,坐下,继续听。

【第一斧】培养联系感,释放可得性

关键词:共同话题+相似处+可得性

第一次约会之前,专门抽出一大段时间,什么事都不干,你只负责一件事:好好捯饬自己!

第一次约会别穿的太诱惑,走可爱清新的路线,这种穿衣风格符合大多数直男的审美,化一个裸妆就会让他觉得你“素颜也好美”了。

虽然这看起来很普通难度不大,但是你每一个装扮都要特别用心,就像vava《我的新衣》里唱的:

“look at me,从上到下,就哪怕小的细节都要美到爆炸。”

约会可以小小的迟到5-10分钟,“赶过来”时,一定要主动道歉:“对不起对不起,堵车了,你没有等的太着急吧。”给他一点着急的感觉,然后再用礼貌的道歉刷一下好感。

约会安排什么的,让他安排,记得夸奖他用心,挑的都是你喜欢的地方,让他小小的洋洋自得一下。

如果他一点规划都没有,只会傻傻的问你你想去哪里……好吧先在内心吐槽一下,然后眨眨眼睛:“我觉得都可以呀,不过我比较喜欢xx(咖啡店,西餐,中餐,日料之类的大方向)”

注意,你去根本不是去和他吃饭的!你需要在喝咖啡吃饭的间歇迅速找到共同话题,如故他主动聊迎合他就好了,如果他紧张的说不出话来,你就主动挑话题吧:

“我看你朋友圈xxxx,经常xxxx吧?”

说话的时候扑闪着你的卡姿兰大眼睛,效果满分。

记得找到共同话题时,补上“原来你也喜欢xxxx啊!我对那个很感兴趣呢”,给他足够卖弄的动力,这样能够拉进你们之间的关系。

光有近距离还不够,这个时候需要释放一些可得性,告诉男生:我单身可撩,你还不给我主动点!

建议这么说:“唉,很少有能和我有一样兴趣爱好的人了,我将来找男朋友一定要找一个志趣相投,聊得来的人,这样才不会无聊呢。”

这个叫做拉,给他一个暗示:唉呀妈呀这不说的就是我吗。

别着急,还有后半段呢:“唉,只可惜现在这样的人太少了,难怪我单身。”

这个叫推,让他一下子又不知所措:啥情况啊?坐你对面的这个不就是吗?

别管他,让他纠结去吧。撩女生我们讲推拉,推出去再哄回来,让女生觉得我们坏但是可爱。对撩男生我们讲拉推,拉过来再一把推开,让男生因为我们到底对他有没有意思而纠结。

相信我,当一个人因为你喜不喜欢他开始纠结时,他就快喜欢上你了。

【第二斧】培养亲密感,激发保护欲

关键词:诱惑+收集心疼

我们不管撩汉撩妹,都要展示给对方积极阳光上进的一面。

但有时候,适当的暴露脆弱面会激发男生本能的保护欲,让他想要在你身边照顾你。

但是千万切忌在朋友圈公开发一些病床照,一些孤独寂寞冷的状态,这样你能引发一群男生来关照你,而男神未必理你,更会招来一堆苍蝇。

趁着第一次约会结束后,给他发一条这样的消息:

“今晚和你聊的很开心,咖啡/饭菜/电影也很合心意,好久没有这么开心过了,下次回请你,哈哈。”

男生说好的没问题最好,要是男生说不用了不用了,直接调皮的回一句:

“怎么滴还不给我一个表达礼貌的机会啦~”

道德绑架就道德绑架吧,这是泡汉子呢,哪来那么多讲究。

至于第二次呢,不要再诱导邀约了,如果他没动静,直接点约他。

这个时候不怕显得主动,因为你顺理成章:这是出于礼节的回请,不要多想哦。

这一次约会,梳妆打扮的要求不能低,依旧要一出场就惊艳,至于怎么做到这一步,你还需要多多请教美妆博主,原谅我这个直男不能给出太多的意见。

这次约会的聊天话题前半段依旧正常的瞎扯淡就好,重点是后半段,你一定要开始刷心疼了。

把你平时和小姐妹诉苦的样子摆出来,告诉男生你其实压力也很大,也很脆弱,也渴望温暖。

但是这不算完,刷心疼注意以下两点:1.不能把刷心疼变成诉苦 2.保证唯一特殊性

我们举个例子:

“宏桑你一直都说我很阳光很正能量,但实际上说句实在话,现在又有谁是真的开心呢?我一个女孩子孤身一人来到北京打拼,虽然白天大家都看到我努力工作特别上进,但有的时候被领导批评,工作不顺时,其实我也会伤心难过。”

“但是那有怎么样呢,回到住的地方,大家都去休息了,还不是一个人去微波炉热一下饭,洗个澡振作一下,然后孤零零的睡。”

“就算有时候实在撑不住了,大哭一场,也得闷着头不能发出声来,怕吵到舍友,也怕被别人知道自己其实并不是全能选手。”

“这些话也就我们今天在这里说一说了,平时我绝对不会对其他人说这么多的,大家都很忙,没时间听太多我的事情。”

“抱歉哈,刚刚情绪有点失控,吓到你了”(擦眼泪,不管有没有)

这个时候,你在男生心目中的形象是:一个自立自强的女孩子,有着温柔脆弱的一面,但是却不知道和谁说,想要找一个依靠。

你说他心疼不心疼,想不想保护你,心中的英雄情节有没有被你激发?

扇风够了,我们再点个火:

分离的时候,认真的看着他,对他说:

“xxx,谢谢你今天能听我说这些,你好体贴。希望我将来能遇到像你一样的人。”

看到了吗?“谢谢你听我说这些”“你好体贴”是拉,“遇到像你一样的人(但可能不是你)”再推开。

让他继续纠结去吧。

【第三斧】亲密互动,引导表白

关键词:高强度诱惑+引导表白

Ok,终于我们来到了第三次约会。这一次其实谁约谁真的不困难了,毕竟前两次都出来一起吃喝玩乐过了。

这次见面,告诉你的小姐妹们,怎么诱惑男人怎么来,不论是妆容还是衣着,按照诱惑力max来打扮。

这次约会项目做什么都无所谓,但是诱惑感一定要到位。

比如聊天时假装被笑话逗得前仰后合,趁机拍拍他;比如在他说话时用小迷妹的眼光盯着他;比如吃饭时悄悄用腿碰碰他的腿;比如他开你玩笑时假装要打他……

诱惑+肢体碰触,除非你丑,不然真的没几个男生扛得住双重引诱。

这个时候你做一个事,就足够让他被你吸引:盯着他,温和的笑,傻傻的笑,就够了。

男生版三板斧约会要求第三次约会确立关系,但是女生很难做到主动去和男生表白,我们不如换个方式。

之前有女粉丝问我男生送她到楼下,摸了摸她的头,她想要更进一步但是发现男生榆木脑袋不开窍,怎么办。

很简单,你只需要在分别时大大方方的告别,走一两步,突然停下,回头,用恨铁不成钢的无奈的笑配上幽怨的语气,轻轻说一句:

“你还真让我走啊?”

就够了,真的就够了!

这句话配合上你的表情,已经传达出了这样的意思:你能不能主动点!你能不能配合点!你居然还真让我回去了,都不抱抱我!你这么笨可以去死了!

这样,男生要么瞬间开窍冲上去对你表白,要么害羞忍住了但是回去一晚上纠结的睡不着觉,要么就是完全无感跟没听见一样。

对于最后一种,我们就算了吧,这都快说出来了他都没反应,说明人家是真的无感。

但是前两种就有戏了,之前你释放了足够的可得性,也激发了他的保护欲,最后这一声叹气,是把他推向你的最后一把。

如果他不上,他的内心都会骂自己不是个爷们!

如果他不说,回去以后。立刻开始对他变冷淡。

你要用行动去告诉他:机会不是没有给过你,你没好好把握。至于本姑娘为什么对你冷淡了,自己琢磨去吧。

就算他想不透,他的狐朋狗友也会拍着他的肩膀告诉他哥们你是傻子吗,这个女生喜欢你啊。

相信我,他会坐不住的,他会主动来找你的,甚至主动表白。

等他绷不住的那一刻,我们只需要摸摸他的头,一把抱住他,娇嗔一句:“笨蛋”

“其实我也喜欢你啊”

看,一桩两全其美的好事,就通过三次约会造就了。