php实现并发处理之curl篇

简介:

php在并发处理方面的确不如java好。但是也有一些方法可以实现并发处理。比如使用curl就可以实现url的并发请求。

看到网上有人说使用curl会导致阻塞,即所有的请求数据都获取完毕后一并返回,然后再进行数据处理。而不是获取一个请求的数据就处理一个数据。其实这种说法是不对的,只能说明他在代码实现上有问题。

在php官方找了段导致阻塞的示例代码,如下:


function multiple_threads_request($nodes){ 
        $mh = curl_multi_init(); 
        $curl_array = array(); 
        foreach($nodes as $i => $url) 
        { 
            $curl_array[$i] = curl_init($url); 
            curl_setopt($curl_array[$i], CURLOPT_RETURNTRANSFER, true); 
            curl_multi_add_handle($mh, $curl_array[$i]); 
        } 
        $running = NULL; 
        do { 
            usleep(10000); 
            curl_multi_exec($mh,$running); 
        } while($running > 0); 
         
        $res = array(); 
        foreach($nodes as $i => $url) 
        { 
            $res[$url] = curl_multi_getcontent($curl_array[$i]); 
        } 
         
        foreach($nodes as $i => $url){ 
            curl_multi_remove_handle($mh, $curl_array[$i]); 
        } 
        curl_multi_close($mh);        
        return $res; 
} 
print_r(muti_thread_request(array( 
    'http://www.example.com', 
    'http://www.example.net', 
)));

下面是边请求url,边处理返回数据的示例代码:


/*
 * @purpose: 使用curl并行处理url
 * @return: array 每个url获取的数据
 * @param: $urls array url列表
 * @param: $callback string 需要进行内容处理的回调函数。示例:func(array)
 */
function curl($urls = array(), $callback = '')
{
    $response = array();
    if (empty($urls)) {
        return $response;
    }
    $chs = curl_multi_init();
    $map = array();
    foreach($urls as $url){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_TIMEOUT, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_NOSIGNAL, true);
        curl_multi_add_handle($chs, $ch);
        $map[strval($ch)] = $url;
    }
    do{
        if (($status = curl_multi_exec($chs, $active)) != CURLM_CALL_MULTI_PERFORM) {
            if ($status != CURLM_OK) { break; } //如果没有准备就绪,就再次调用curl_multi_exec
            while ($done = curl_multi_info_read($chs)) {
                $info = curl_getinfo($done["handle"]);
                $error = curl_error($done["handle"]);
                $result = curl_multi_getcontent($done["handle"]);
                $url = $map[strval($done["handle"])];
                $rtn = compact('info', 'error', 'result', 'url');
                if (trim($callback)) {
                    $callback($rtn);
                }
                $response[$url] = $rtn;
                curl_multi_remove_handle($chs, $done['handle']);
                curl_close($done['handle']);
                //如果仍然有未处理完毕的句柄,那么就select
                if ($active > 0) {
                    curl_multi_select($chs, 0.5); //此处会导致阻塞大概0.5秒。
                }
            }
        }
    }
    while($active > 0); //还有句柄处理还在进行中
    curl_multi_close($chs);
    return $response;
}
 
//使用方法
function deal($data){
    if ($data["error"] == '') {
        echo $data["url"]." -- ".$data["info"]["http_code"]."\n";
    } else {
        echo $data["url"]." -- ".$data["error"]."\n";
    }
}
$urls = array();
for ($i = 0; $i < 10; $i++) {
    $urls[] = 'http://www.baidu.com/s?wd=etao_'.$i;
    $urls[] = 'http://www.so.com/s?q=etao_'.$i;
    $urls[] = 'http://www.soso.com/q?w=etao_'.$i;
}
curl($urls, "deal"); 

演示网址 http://demo.bo56.com/bigpipe/

注释:
1.关于curl_multi_exec函数的返回值:
返回CURLM_CALL_MULTI_PERFORM 说明curl_multi_exec需要马上被再调用一次。
返回CURLM_OK 说明已经有需要处理的数据。这时你需要进行相关处理,处理完后再次调用curl_multi_exec。
php中的curl_multi_exec是调用的curl库中的curl_multi_perform方法。代码在multi.c的230行左右。

2.此方式,虽然在获取数据和数据处理上是并行的,但是在数据处理时依然是串行的。即数据是一条条依次处理的。如果deal方法比较耗时的话,那整体会非常耗时。



目录
相关文章
|
6月前
|
JSON PHP 数据格式
PHP curl方法封装
PHP curl方法封装
89 0
|
5月前
|
PHP
php使用curl新增微信临时素材(上传图片)
php使用curl新增微信临时素材(上传图片)
252 4
|
5月前
|
JSON PHP 数据格式
蓝易云 - PHP用CURL发送Content-type为application/json的POST请求方法
在这段代码中,我们首先创建了一个包含我们要发送的数据的数组,并使用 `json_encode`函数将其转换为JSON格式。然后,我们初始化了一个cURL会话,并设置了一些选项,包括POST请求方法、要发送的数据、返回结果和HTTP头部信息。最后,我们执行了cURL请求并关闭了会话。
141 2
|
5月前
|
Web App开发 API PHP
PHP封装的不错的一个Curl方法
This is a PHP function named `teacher_curl` that wraps around the cURL library for making HTTP requests. The function initializes a cURL session, sets various options such as disabling SSL verification, sets headers, handles POST data
139 0
|
5月前
|
网络协议 Linux API
php curl执行太慢解决
网站访问快速,但API接口由curl_exec调用时遭遇显著延迟。问题根源在于DNS配置不当。切换至常用DNS,如114.114.114.114,立即提升了接口响应速度。
149 0
|
6月前
|
监控 PHP 数据库
【PHP开发专栏】PHP事务处理与并发控制
【4月更文挑战第29天】本文探讨了PHP中事务处理和并发控制的核心概念。事务处理确保数据完整性和一致性,具备ACID属性。PHP通过MySQLi和PDO扩展支持事务,示例展示了如何开启、提交和回滚事务。并发控制关注多用户环境下的数据一致性,涉及乐观锁和悲观锁策略。选择合适的事务隔离级别、避免长时间锁定、利用乐观锁以及监控调优是关键实践。理解这些原理有助于优化数据库应用的性能和稳定性。
74 0
|
6月前
|
PHP
php curl获取cookie
php curl获取cookie
44 0
|
6月前
|
PHP 数据格式
PHP 中的CURL 模拟表单的post提交
PHP 中的CURL 模拟表单的post提交
104 0
|
域名解析 网络协议 应用服务中间件
PHP CURL指定host内网通信
PHP CURL指定host内网通信
333 1
PHP CURL指定host内网通信