1.背景:
总所周知,nts版本的PHP是不支持多线程的,毕竟NTS(非线程安全)嘛,有人会说那为何不用多进程呢?嗯,多进程是可以,但是你要考虑到进程通信这个老大难啊,我知道你可能接下来扩展出两个问题,第一个是进程通信的必要性,第二个是有哪些方式让进程之间进行高效通信。能这么想就对了,但是本文解决的问题是突破PHP单进程单线程利用网络进行数据采集的瓶颈而创作的,因此这俩问题就交给同学们自己去搜索答案了。
2.解决步骤:
2.1 打开:https://packagist.org
2.2 搜索curlmulti,找到一个满足自己需求的pkg并查看文档描述:https://packagist.org/packages/phpdr.net/php-curlmulti
2.3 写代码:
composer require phpdr.net/php-curlmulti
<?php require_once __DIR__.'/vendor/autoload.php'; use Ares333\CurlMulti\Core; $urls = []; for($i = 0; $i<1000; $i++){ $urls[] = "https://www.baidu.com"; } $curl = new Core (); $curl->maxThread = 50; foreach ( $urls as $v ) { $curl->add ( array ( 'url' => $v, 'args' => array ( 'test' => 'this is user arg for ' . $v ) ), 'cbProcess' ); } $start = microtime(true); $curl->start (); echo "\n"; echo microtime(true) - $start; function cbProcess($r, $args) { static $i = 0; file_put_contents(__DIR__."/baidu/".$i.".log", $r['content']); $i++; }
//消耗时间:17.40699505806
去掉file_put_contents并把采集到的内容放到全局数组里面去,发现耗时11秒,
<?php require_once __DIR__.'/vendor/autoload.php'; use Ares333\CurlMulti\Core; $urls = []; for($i = 0; $i<1000; $i++){ $urls[] = "https://www.baidu.com"; } $curl = new Core (); $curl->maxThread = 50; foreach ( $urls as $v ) { $curl->add ( array ( 'url' => $v, 'args' => array ( 'test' => 'this is user arg for ' . $v ) ), 'cbProcess' ); } $start = microtime(true); $curl->start (); echo "\n"; echo microtime(true) - $start; $content = []; function cbProcess($r, $args) { static $i = 0; global $content; //file_put_contents(__DIR__."/baidu/".$i.".log", $r['content']); $content[] = $r['content']; $i++; } //11.546661138535
目的基本达到,同学们可以根据自己的网络情况再进行自己的优化。
本文原创文章同步发表在:https://wenda.shukaiming.com/article/18
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!