小兔网

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中可以根据发送过来的参数来处理请求,就可以模拟多进程的并行提交了.....同时也可以应用进行数据访问的测试!