尝试为curl处理程序制作5个curl childs并定义它们,但找不到最好的方法..到目前为止我的代码
$curls = array($ch1, $ch2, $ch3, $ch4, $ch5); // have a bad feelin about this
$cont = array($cont1, $cont2, $cont3, $cont4, $cont5); // bad
for($i = 0; $i < count($curls); $i++) { // bad
$curls[$i] = curl_init();
curl_setopt($curls[$i], CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curls[$i], CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curls[$i], CURLOPT_REFERER, $ref);
curl_setopt($curls[$i], CURLOPT_USERAGENT, $useragent);
curl_setopt($curls[$i], CURLOPT_COOKIEFILE, $cookiefile);
curl_setopt($curls[$i], CURLOPT_COOKIEJAR, $cookiefile);
curl_setopt($curls[$i], CURLOPT_URL, $url);
curl_setopt($curls[$i], CURLOPT_POST, true);
curl_setopt($curls[$i], CURLOPT_POSTFIELDS, $data);
$cont[$i] = curl_exec($curls[$i]); // bad
curl_setopt($curls[$i], CURLOPT_URL, $url);
curl_setopt($curls[$i], CURLOPT_POST, true);
curl_setopt($curls[$i], CURLOPT_POSTFIELDS, $data);
$cont[$i] = curl_exec($curls[$i]); // bad
}
以后:
$mh = curl_multi_init();
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);
curl_multi_add_handle($mh,$ch3);
curl_multi_add_handle($mh,$ch4);
curl_multi_add_handle($mh,$ch5);
这样做还是......这是最佳方式吗?看起来有点坎坷
答案 0 :(得分:1)
我实际上会以不同的方式处理这个问题。我将创建一个函数来处理curl
的单个实例的创建,并使用参数根据需要调整变量设置。这让我可以创建一个实例,或者我可以创建一个循环来创建多个实例。
问题是,很多时候多个curl调用取决于前一个调用是否成功。如果第一个没有成功,我现在浪费地分配了多个卷曲对象。创建第一个,运行它,错误检查,创建第二个,运行它,错误检查等等。这样你只需要分配你需要的东西。
修改 :这样的事情
// get the result of a single curl call
function makeCurlCall($ref, $useragent, $cookiefile, $url, $data)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_REFERER, $ref);
curl_setopt($curl, CURLOPT_USERAGENT, $useragent);
curl_setopt($curl, CURLOPT_COOKIEFILE, $cookiefile);
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookiefile);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$cont = curl_exec($curl);
// May need to use this later
$error_no = curl_errno($curl);
if($error_no) {
// so we can close before we return
$result = "[" . $error_no . "] " . curl_error($curl);
curl_close($curl);
return array('status' => 'error', 'result' => $result);
}
else {
curl_close($curl);
return array('status' => 'success', 'result' => $cont);
}
}
$curl = makeCurlCall($ref, $useragent, $cookiefile, $url, $data);
if($curl['status'] == 'error') {
// do something for the error
}
else {
// do something with $curl['result']
}
// The first call worked, so make the next call, only allocating what we need
$curl = makeCurlCall($ref, $useragent, $cookiefile, $url, $data);
//etc.
请注意,如果它足够通用,您可能会包含处理错误和成功的功能,但是您仍然需要处理由于网络问题导致单个卷曲调用无法正常工作的问题等。
答案 1 :(得分:0)
你可以尝试这样的事情。我不确定它是否适用于您的场景,但这是一个开始。
function makeCurl($ref, $useragent, $cookiefile, $url, $data){
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_REFERER, $ref);
curl_setopt($curl, CURLOPT_USERAGENT, $useragent);
curl_setopt($curl, CURLOPT_COOKIEFILE, $cookiefile);
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookiefile);
curl_setopt($curl, CURLOPT_URL, $url);
if($data){
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
return $curl;
}
// first let's login
$login = makeCurl($loginref, $useragent, $cookiefile, $loginurl, $logindata);
curl_exec($login);
curl_close($login);
// $cookiefile now has the needed cookies
// for the parallel jobs to run
$curls = array();
$mh = curl_multi_init();
$curls[0] = makeCurl($ref, $useragent, $cookiefile, $url, $data);
$curls[1] = makeCurl($ref, $useragent, $cookiefile, $url, $data);
$curls[2] = makeCurl($ref, $useragent, $cookiefile, $url, $data);
$curls[3] = makeCurl($ref, $useragent, $cookiefile, $url, $data);
$curls[4] = makeCurl($ref, $useragent, $cookiefile, $url, $data);
$curls[5] = makeCurl($ref, $useragent, $cookiefile, $url, $data);
for($i = 0; $i < count($curls); $i++){
curl_multi_add_handle($mh, $curls[$i]);
}
// use curl_multi_exec to run them and wait for them to finish
// (I've never done this before, so i can't tell you how to do it)