Home >Backend Development >PHP Tutorial >PHP多线程之内部多线程实例分析_PHP

PHP多线程之内部多线程实例分析_PHP

WBOY
WBOYOriginal
2016-05-31 13:13:36770browse

本文实例分析了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";

希望本文所述对大家的php程序设计有所帮助。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn