curl_multi_init函数
(PHP 5)
curl_multi_init — 返回一个新cURL批处理句柄
说明
resource curl_multi_init ( void )
允许并行地处理批处理cURL句柄。
参数
此函数没有参数。
返回值
成功时返回一个cURL批处理句柄,失败时返回FALSE。
实例
这个范例将会创建2个cURL句柄,把它们加到批处理句柄,然后并行地运行它们。
PHP curl_multi_exec函数
(PHP 5)
curl_multi_exec — 运行当前 cURL 句柄的子连接
说明
int curl_multi_exec ( resource $mh , int &$still_running )
处理在栈中的每一个句柄。无论该句柄需要读取或写入数据都可调用此方法。
参数
mh
由 curl_multi_init() 返回的 cURL 多个句柄。
still_running
一个用来判断操作是否仍在执行的标识的引用。
返回值
一个定义于 cURL 预定义常量中的 cURL 代码。
注意: 该函数仅返回关于整个批处理栈相关的错误。即使返回 CURLM_OK 时单个传输仍可能有问题。
实例
这个范例将会创建 2 个 cURL 句柄,把它们加到批处理句柄,然后并行地运行它们。
<?php// 创建一对cURL资源$ch1 = curl_init();$ch2 = curl_init();// 设置URL和相应的选项curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/");curl_setopt($ch1, CURLOPT_HEADER, 0);curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/");curl_setopt($ch2, CURLOPT_HEADER, 0);// 创建批处理cURL句柄$mh = curl_multi_init();// 增加2个句柄curl_multi_add_handle($mh,$ch1);curl_multi_add_handle($mh,$ch2);$active = null;// 执行批处理句柄do { $mrc = curl_multi_exec($mh, $active);} while ($mrc == CURLM_CALL_MULTI_PERFORM);while ($active && $mrc == CURLM_OK) { if (curl_multi_select($mh) != -1) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); }}// 关闭全部句柄curl_multi_remove_handle($mh, $ch1);curl_multi_remove_handle($mh, $ch2);curl_multi_close($mh);?>
php curl 多线程
$offmh = curl_multi_init(); //开启curl多线程
foreach ($offer as $i => $url) {
$conn[$i] = curl_init($url); //开启curl
curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, true);// 执行后不直接打印出来
curl_setopt($conn[$i], CURLOPT_POST, true); //设置请求方式为post
curl_setopt($conn[$i], CURLOPT_POSTFIELDS,$post_data);//post的变量
curl_setopt($conn[$i], CURLOPT_HEADER ,false); // 请求头,可以传数组
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"); //在HTTP请求中包含一个”user-agent”头的字符串。
curl_setopt($conn[$i], CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($conn[$i], CURLOPT_SSL_VERIFYHOST, false); // 不从证书中检查SSL加密算法是否存在
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,10); //标识如果服务器10秒内没有响应,脚本就会断开连接;
curl_multi_add_handle ($offmh,$conn[$i]); //创建n个cURL句柄,把它们加到批处理句柄,然后并行地运行它们。
}
// 执行批处理句柄
$active = null;
do{
$mrc = curl_multi_exec($offmh,$active);//当无数据,active=true
} while ($mrc == CURLM_CALL_MULTI_PERFORM);//当正在接受数据时
while ($active && $mrc == CURLM_OK) {//当无数据时或请求暂停时,active=true
do{
$mrc = curl_multi_exec($offmh, $active);
}while($mrc == CURLM_CALL_MULTI_PERFORM);
}
foreach ($offer as $k => $url) {
$dooffer = curl_multi_getcontent($conn[$k]);//获得返回信息
//处理数据
curl_close($conn[$k]);//关闭语柄
curl_multi_remove_handle($offmh, $conn[$k]);//释放资源
}
curl_multi_close($offmh); //关闭curl多线程
示例3
<?php
/**
* curl 多线程
* @param array $array 并行网址
* @param int $timeout 超时时间
* @return array
*/
function Curl_http($array,$timeout){
$res = array();
$mh = curl_multi_init();//创建多个curl语柄
foreach($array as $k=>$url){
$conn[$k]=curl_init($url);
curl_setopt($conn[$k], CURLOPT_TIMEOUT, $timeout);//设置超时时间
curl_setopt($conn[$k], CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
curl_setopt($conn[$k], CURLOPT_MAXREDIRS, 7);//HTTp定向级别
curl_setopt($conn[$k], CURLOPT_HEADER, 0);//这里不要header,加块效率
curl_setopt($conn[$k], CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
curl_setopt($conn[$k],CURLOPT_RETURNTRANSFER,1);
curl_multi_add_handle ($mh,$conn[$k]);
}
// 执行批处理句柄
$active = null;
do{
$mrc = curl_multi_exec($mh,$active);//当无数据,active=true
}while($mrc == CURLM_CALL_MULTI_PERFORM);//当正在接受数据时
while($active && $mrc == CURLM_OK){//当无数据时或请求暂停时,active=true
// if(curl_multi_select($mh) != -1){
do{
$mrc = curl_multi_exec($mh, $active);
}while($mrc == CURLM_CALL_MULTI_PERFORM);
// }
}
foreach ($array as $k => $url) {
curl_error($conn[$k]);
$res[$k]=curl_multi_getcontent($conn[$k]);//获得返回信息
$header[$k]=curl_getinfo($conn[$k]);//返回头信息
curl_close($conn[$k]);//关闭语柄
curl_multi_remove_handle($mh , $conn[$k]);//释放资源
}
curl_multi_close($mh);
return $res;
//测试
$array = array(
"http://www.weibo.com/",
"http://www.renren.com/",
"http://www.qq.com/"
);
$data = Curl_http($array,'10');//调用
print_r($data);//输出
exit;
?>
这个多线程的写法步骤:
第一步:调用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
示例4
php不想java可以直接继承Thread接口或者实现Runnable接口,进行多线程的开发,不过php中提供了强大的curl工具支持多线程,
php中可以使用curl_multi_init()等来模仿并行处理和多线程程序功能。同时可以使用curl_multi_init()模仿多线程的提交。如下面程序所示:
<?php
include "log.php";
$stime=microtime(true);
$urls = array(
"http://localhost/index.php",
"http://localhost/index.php",
"http://localhost/index.php",
"http://localhost/index.php",
"http://localhost/index.php",
"http://localhost/index.php",
"http://localhost/index.php",
);
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1);
curl_setopt($conn[$i], CURLOPT_POST, 1);
curl_setopt($conn[$i], CURLOPT_POSTFIELDS, array('offset'=>$i)); //提交数据
curl_multi_add_handle($mh, $conn[$i]);
}
do {
$status = curl_multi_exec($mh, $active);
$info = curl_multi_info_read($mh);
if (false !== $info) {
//var_dump($info);
}
} while ($status === CURLM_CALL_MULTI_PERFORM || $active);
foreach ($urls as $i => $url) {
$res[$i] = curl_multi_getcontent($conn[$i]); //获取返回内容
curl_close($conn[$i]);
}
echo "<pre>";
print_r($res);
$etime=microtime(true);//获取程序执行结束的时间
$total=$etime-$stime; //计算差值
$str_total = var_export($total, TRUE);
echo $str_total;
程序启动7个curl分别向index.php页面发送请求,在index.php中可以根据发送过来的参数来处理请求,就可以模拟多进程的并行提交了.....同时也可以应用进行数据访问的测试!