最近写一个php采集类程序脚本,研究了snoopy采集类,同时在搜集相关资料时发现curl_multi可用于多线程,于是进行了测试,实践证明效果相对很好。例子可参考 花瓣网图片采集器。下面是相关知识介绍,仅作参考。
curl_multi函数介绍
php中的curl_multi一族函数可用于多线程处理等问题,包括如下函数:
curl_multi_add_handle
curl_multi_close
curl_multi_exec
curl_multi_getcontent
curl_multi_info_read
curl_multi_init
curl_multi_remove_handle
curl_multi_select
curl函数参考
curl_init — 初始化一个curl会话
curl_copy_handle — 拷贝一个curl连接资源的所有内容和参数
curl_errno — 返回一个包含当前会话错误信息的数字编号
curl_error — 返回一个包含当前会话错误信息的字符串
curl_exec — 执行一个curl会话
curl_getinfo — 获取一个curl连接资源句柄的信息
curl_multi_init — 初始化一个curl批处理句柄资源
curl_multi_add_handle — 向curl批处理会话中添加单独的curl句柄资源
curl_multi_close — 关闭一个批处理句柄资源
curl_multi_exec — 解析一个curl批处理句柄
curl_multi_getcontent — 返回获取的输出的文本流
curl_multi_info_read — 获取当前解析的curl的相关传输信息
curl_multi_remove_handle — 移除curl批处理句柄资源中的某个句柄资源
curl_multi_select — Get all the sockets associated with the cURL extension, which can then be "selected"
curl_setopt_array — 以数组的形式为一个curl设置会话参数
curl_setopt — 为一个curl设置会话参数
curl_version — 获取curl相关的版本信息
curl_close — 关闭一个curl会话
一般来说,想到要用这些函数时,目的显然应该是要同时请求多个url,而不是一个一个依次请求,否则不如自己循环去调curl_exec好了。
curl_muti函数使用方法
使用步骤总结如下:
第一步:调用curl_multi_init
第二步:循环调用curl_multi_add_handle
这一步需要注意的是,curl_multi_add_handle的第二个参数是由curl_init而来的子handle。
第三步:持续调用curl_multi_exec
第四步:根据需要循环调用curl_multi_getcontent获取结果
第五步:调用curl_multi_remove_handle,并为每个字handle调用curl_close
第六步:调用curl_multi_close
curl_multi多线程示例
这里有一个网上的一个例子,用于多线程并行采集多个页面内容,代码如下:
/**
* Perform parallel cURL request.
*
* @param array $urls Array of URLs to make request.
* @param array $options (Optional) Array of additional cURL options.
* @return mixed Results from the request (if any).
*/
function curlMultiRequest($urls, $options = array()) {
$ch = array();
$results = array();
$mh = curl_multi_init();
foreach($urls as $key => $val) {
$ch[$key] = curl_init();
if ($options) {
curl_setopt_array($ch[$key], $options);
}
curl_setopt($ch[$key], CURLOPT_URL, $val);
curl_multi_add_handle($mh, $ch[$key]);
}
$running = null;
do {
curl_multi_exec($mh, $running);
}
while ($running > 0);
// Get content and remove handles.
foreach ($ch as $key => $val) {
$results[$key] = curl_multi_getcontent($val);
curl_multi_remove_handle($mh, $val);
}
curl_multi_close($mh);
return $results;
}