PHP多线程之内部多线程实例分析
程序员文章站
2023-11-11 18:23:34
本文实例分析了php多线程之内部多线程用法。分享给大家供大家参考。具体如下:
复制代码 代码如下:
本文实例分析了php多线程之内部多线程用法。分享给大家供大家参考。具体如下:
复制代码 代码如下:
<?php
class http_multirequest
{
//要并行抓取的url 列表
private $urls = array();
//curl 的选项
private $options;
//构造函数
function __construct($options = array())
{
$this->setoptions($options);
}
//设置url 列表
function seturls($urls)
{
$this->urls = $urls;
return $this;
}
//设置选项
function setoptions($options)
{
$options[curlopt_returntransfer] = 1;
if (isset($options['http_post']))
{
curl_setopt($ch, curlopt_post, 1);
curl_setopt($ch, curlopt_postfields, $options['http_post']);
unset($options['http_post']);
}
if (!isset($options[curlopt_useragent]))
{
$options[curlopt_useragent] = 'mozilla/4.0 (compatible; msie 6.0; windows nt 5.1; sv1;)';
}
if (!isset($options[curlopt_followlocation]))
{
$options[curlopt_followlocation] = 1;
}
if (!isset($options[curlopt_header]))
{
$options[curlopt_header] = 0;
}
$this->options = $options;
}
//并行抓取所有的内容
function exec()
{
if(empty($this->urls) || !is_array($this->urls))
{
return false;
}
$curl = $data = array();
$mh = curl_multi_init();
foreach($this->urls as $k => $v)
{
$curl[$k] = $this->addhandle($mh, $v);
}
$this->execmulithandle($mh);
foreach($this->urls as $k => $v)
{
$data[$k] = curl_multi_getcontent($curl[$k]);
curl_multi_remove_handle($mh, $curl[$k]);
}
curl_multi_close($mh);
return $data;
}
//只抓取一个网页的内容。
function execone($url)
{
if (empty($url)) {
return false;
}
$ch = curl_init($url);
$this->setoneoption($ch);
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
//内部函数,设置某个handle 的选项
private function setoneoption($ch)
{
curl_setopt_array($ch, $this->options);
}
//添加一个新的并行抓取 handle
private function addhandle($mh, $url)
{
$ch = curl_init($url);
$this->setoneoption($ch);
curl_multi_add_handle($mh, $ch);
return $ch;
}
//并行执行(这样的写法是一个常见的错误,我这里还是采用这样的写法,这个写法
//下载一个小文件都可能导致cup占用100%, 并且,这个循环会运行10万次以上
//这是一个典型的不懂原理产生的错误。这个错误在php官方的文档上都相当的常见。)
private function execmulithandle($mh)
{
$running = null;
do {
curl_multi_exec($mh, $running);
} while ($running > 0);
}
}
/*下面是上面的类的一个测试的例子:*/
$urls = array("http://baidu.com", "http://baidu.com", "http://baidu.com", "http://baidu.com", "http://baidu.com", "http://baidu.com", "http://www.google.com", "http://www.sina.com.cn", );
$m = new http_multirequest();
$t = microtime(true);
$m->seturls($urls);
//parallel fetch(并行抓取):
$data = $m->exec();
$parallel_time = microtime(true) - $t;
echo $parallel_time . "\n";
$t = microtime(true);
//serial fetch(串行抓取):
foreach ($urls as $url)
{
$data[] = $m->execone($url);
}
$serial_time = microtime(true) - $t;
echo $serial_time . "\n";
class http_multirequest
{
//要并行抓取的url 列表
private $urls = array();
//curl 的选项
private $options;
//构造函数
function __construct($options = array())
{
$this->setoptions($options);
}
//设置url 列表
function seturls($urls)
{
$this->urls = $urls;
return $this;
}
//设置选项
function setoptions($options)
{
$options[curlopt_returntransfer] = 1;
if (isset($options['http_post']))
{
curl_setopt($ch, curlopt_post, 1);
curl_setopt($ch, curlopt_postfields, $options['http_post']);
unset($options['http_post']);
}
if (!isset($options[curlopt_useragent]))
{
$options[curlopt_useragent] = 'mozilla/4.0 (compatible; msie 6.0; windows nt 5.1; sv1;)';
}
if (!isset($options[curlopt_followlocation]))
{
$options[curlopt_followlocation] = 1;
}
if (!isset($options[curlopt_header]))
{
$options[curlopt_header] = 0;
}
$this->options = $options;
}
//并行抓取所有的内容
function exec()
{
if(empty($this->urls) || !is_array($this->urls))
{
return false;
}
$curl = $data = array();
$mh = curl_multi_init();
foreach($this->urls as $k => $v)
{
$curl[$k] = $this->addhandle($mh, $v);
}
$this->execmulithandle($mh);
foreach($this->urls as $k => $v)
{
$data[$k] = curl_multi_getcontent($curl[$k]);
curl_multi_remove_handle($mh, $curl[$k]);
}
curl_multi_close($mh);
return $data;
}
//只抓取一个网页的内容。
function execone($url)
{
if (empty($url)) {
return false;
}
$ch = curl_init($url);
$this->setoneoption($ch);
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
//内部函数,设置某个handle 的选项
private function setoneoption($ch)
{
curl_setopt_array($ch, $this->options);
}
//添加一个新的并行抓取 handle
private function addhandle($mh, $url)
{
$ch = curl_init($url);
$this->setoneoption($ch);
curl_multi_add_handle($mh, $ch);
return $ch;
}
//并行执行(这样的写法是一个常见的错误,我这里还是采用这样的写法,这个写法
//下载一个小文件都可能导致cup占用100%, 并且,这个循环会运行10万次以上
//这是一个典型的不懂原理产生的错误。这个错误在php官方的文档上都相当的常见。)
private function execmulithandle($mh)
{
$running = null;
do {
curl_multi_exec($mh, $running);
} while ($running > 0);
}
}
/*下面是上面的类的一个测试的例子:*/
$urls = array("http://baidu.com", "http://baidu.com", "http://baidu.com", "http://baidu.com", "http://baidu.com", "http://baidu.com", "http://www.google.com", "http://www.sina.com.cn", );
$m = new http_multirequest();
$t = microtime(true);
$m->seturls($urls);
//parallel fetch(并行抓取):
$data = $m->exec();
$parallel_time = microtime(true) - $t;
echo $parallel_time . "\n";
$t = microtime(true);
//serial fetch(串行抓取):
foreach ($urls as $url)
{
$data[] = $m->execone($url);
}
$serial_time = microtime(true) - $t;
echo $serial_time . "\n";
希望本文所述对大家的php程序设计有所帮助。
上一篇: js实现简单的获取验证码按钮效果
下一篇: php实现在服务器上创建目录的方法