我已经设置了一个小脚本来使用curl_multi_ *代码的已知cUrl功能来提供异步非阻塞请求,这是代码的粗略版本:
$mch = curl_multi_init();
$ch = curl_init();
url_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_multi_add_handle($mch ,$ch);
$running = null;
do {
curl_multi_exec($mch ,$running);
} while($running > 0);
curl_multi_remove_handle($mch,$ch);
curl_close($ch);
基本上这用于发送一个请求作为并行请求,以允许代码继续运行,而另一个脚本通过cURL调用,我不关心结果,因此我没有使用代码来处理它我只想要其他在curl调用后的代码将继续运行时调用脚本。
首先,我不明白为什么我需要while循环,不会为一个请求工作调用multi_exec一次?因为不使用循环不会在$ url上运行脚本(我选中了)。
其次和我最大的问题,这应该是异步的,我尝试将sleep(10)放在另一个脚本上,并且调用脚本在继续之前等待10秒,我不明白它应该是非阻塞的并且应该继续运行。
我做错了什么?
答案 0 :(得分:4)
让我们从最后开始。
当您的PHP完成运行脚本时,它会执行清理并终止所有仍在运行的curl句柄。重要的是要记住这一点。
现在,每个curl请求分为多个步骤,如初始化连接,连接,写入数据,读取数据,关闭连接。可以重复中间步骤。而且我确信实际上幕后发生了更复杂的事情,但总的来说这个描述应该是正确的。
curl_multi_exec控制多句柄中的每个句柄,并允许它执行下一步,无论它是什么。然后函数返回。
这解释了为什么没有循环就没有看到请求的原因。这是因为您的句柄尚未到达能够执行实际连接的步骤。你的PHP脚本完成运行,执行清理,进而杀死句柄,根本没有机会做任何事情。
所以,现在很明显,你需要给你机会做点什么。一遍又一遍地运行curl_multi_exec是实现它的一种方法。
这解释了为什么你遇到等待,这些多句柄并不是真正的异步,它们看起来就像它们一样。你的循环给出了运行的机会,循环将一直运行直到请求完成(在你的例子中需要10秒)。
简短摘要:您需要找到问题的另一种解决方案(即继续运行其他代码,同时执行curl):))
答案 1 :(得分:0)
这个对我有用:
function get_web_page( $url )
{
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // don't return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_USERAGENT => "spider", // who am i
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
);
$ch = curl_init( $url );
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['content'] = $content;
return $header;
}
作为一项功能,您可以反复调用它。 (作为异步线程)所以你需要做的就是编写一个while循环来处理接收和处理所有收到的卷发..一旦完成,你的脚本就可以完成,避免在代码问题结束时停止。
另一点......你不需要像这样格式化你的while循环..
do { ... } while (conditional)
你可以使用:
while (conditional) { ... }