我的网站上有一个表单,通过cURL调用web服务,提交后发布数据。
这种情况很有效,除非在一种情况下,当远程Web服务服务器关闭时(经常发生) 所以我试图开发一个缓存系统,其工作原理如下:
问题是如何进行最后一步? URL始终是相同的(每次调用只更改POST字段)我想检查每个调用是否有效(让我们想象一下,在第一次提交后,远程服务器会停止运行,我想保存在我的调用中数据库,前10个是好的但不是其他的左边)
我试过这个功能,我发现:
function curl_multiRequest($data, $options = array()) {
// array of curl handles
$curly = array();
// data to be returned
$result = array();
// multi handle
$mh = curl_multi_init();
// loop through $data and create curl handles
// then add them to the multi-handle
foreach ($data as $id => $d) {
$curly[$id] = curl_init();
$url = (is_array($d) && !empty($d['url'])) ? $d['url'] : $d;
curl_setopt($curly[$id], CURLOPT_URL, $url);
curl_setopt($curly[$id], CURLOPT_HEADER, 0);
curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, 1);
// post?
if (is_array($d)) {
if (!empty($d['post'])) {
curl_setopt($curly[$id], CURLOPT_POST, 1);
curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $d['post']);
}
}
// extra options?
if (!empty($options)) {
curl_setopt_array($curly[$id], $options);
}
curl_multi_add_handle($mh, $curly[$id]);
}
// execute the handles
$running = null;
do {
curl_multi_exec($mh, $running);
} while($running > 0);
// get content and remove handles
foreach($curly as $id => $c) {
$result[$id] = curl_multi_getcontent($c);
curl_multi_remove_handle($mh, $c);
}
// all done
curl_multi_close($mh);
return $result;
}
我的数组看起来像:
array(5) {
[0]=>
array(6) {
["id"]=>
string(1) "7"
["post"]=>
string(1644) "Surname=Test&Name=Test"
["url"]=>
string(28) "http://www.mywebsite.fr/"
}
[1]=>
array(6) {
["id"]=>
string(1) "6"
["post"]=>
string(1644) "Surname=Test1&Name=Test1"
["url"]=>
string(28) "http://www.mywebsite.fr/"
}
[2]=>
array(6) {
["id"]=>
string(1) "5"
["post"]=>
string(1644) "Surname=Test2&Name=Test2"
["url"]=>
string(28) "http://www.mywebsite.fr/"
}
}
但是当URL无效时(我尝试使用无效的URL来模拟服务器)我有这个:
Fatal error: Maximum execution time of 30 seconds exceeded in /home/www/myscript.php on line 63
Warning: (null)(): 560 is not a valid cURL handle resource in Unknown on line 0
我做错了吗?
谢谢
编辑1:我试图实施这样的主教回答:
$myarray=array(
array(
"id"=>"1",
"post"=>"Surname=Test&Name=Test",
"url"=>"http://www.mywebsite.fr/",
)
, array(
"id"=>"1",
"post"=>"Surname=Test&Name=Test",
"url"=>"http://www.mywebsite.fr/",
)
);
$mh = curl_multi_init();
foreach($myarray as $k=>$failed){
$myarray[$k]["handle"] = curl_init();
curl_setopt($myarray[$k]["handle"], CURLOPT_URL, $failed["url"]);
curl_setopt($myarray[$k]["handle"], CURLOPT_POST, true);
curl_setopt($myarray[$k]["handle"], CURLOPT_POSTFIELDS, $failed["post"]);
curl_multi_add_handle($mh, $myarray[$k]["handle"]);
}
foreach (multiread($mh) as $info) {
var_dump($info);
}
但是如果远程URL无法访问,请求似乎永远不会停止。有没有办法限制每个请求执行的时间?
编辑2: 在定义选项时使用它是一种好方法吗?
curl_setopt($chs[$key], CURLOPT_CONNECTTIMEOUT , 10);
并位于脚本顶部
set_time_limit(0);
如果可以,我的最后一个问题是收集有关每个电话的信息。如何单独检索有关每个处理程序的信息(在数据库中保存此调用是否成功?)像ID一样?
答案 0 :(得分:0)
您在多手柄上的循环看起来并不完整。更强大的实施:
function multiread($mh, $timeout = .5) {
$output = array ();
$runCnt = 0;
do {
// start requests, or update status of pending requests: returns by
// reference (in $runCnt) the number of outstanding requests
$status = curl_multi_exec($mh, $runCnt);
if (CURLM_OK !== $status) throw new \RuntimeException;
// take a breath, so as to not eat 100% CPU
do {
$status = curl_multi_select($mh, $timeout);
if (-1 === $status) {
usleep(10);
}
} while (0 === $status);
// gather the results and yield back what we know
while (false !== ($info = curl_multi_info_read($mh))) {
if (CURLE_OK === $info['result']) {
$output[] = [ $info, curl_multi_getcontent($info['handle']) ];
} else {
$output[] = [ $info, null ];
}
}
} while (0 < $runCnt);
return $output;
}
现在做一些循环:
$mh = curl_multi_init();
// ... add your easy handles
foreach (multiread($mh) as list ($info, $content)) {
// $info['handle'] contains the cURL easy handle
// $info['result'] contains the result code, see also curl_strerror
// $content contains whatever the URL returned
}