【发布时间】:2017-08-06 14:11:41
【问题描述】:
我的网站上有一个表单,通过 cURL 调用 web 服务,并在提交时发布数据。
这很好用,除了在一种情况下,当远程 Web 服务服务器关闭时(它经常发生) 所以我正在尝试开发一个缓存系统,其工作方式如下:
- 如果表单提交上的 curl 执行返回 false,我将其保存在数据库中
- 我每天都在运行一个 CRON 作业来检查我是否有一些失败的提交
- 我正在对我的结果集进行 foreach 并为每个提交运行 curl 调用
问题是如何进行最后一步? URL 总是相同的(只是每次调用的 POST 字段都会发生变化),我想检查每个调用是否有效(假设远程服务器在第 10 次提交后关闭,我想在我的数据库中保存第一个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 左右?
【问题讨论】:
-
给定的示例对我有用(即,它返回相当快的响应)。有没有给您带来麻烦的特定 URL?
-
不,我只是在尝试使用不存在的 URL 来模拟远程服务器。我从另一台服务器上试过,它似乎工作得更好,但回声只是:NULL
-
默认情况下,curl 输出结果。您想返回结果。在初始化循环中,添加:
curl_setopt($myarray[$k]["handle"], CURLOPT_RETURNTRANSFER, true); -
好的,很高兴知道。但是我正在调用三个 URL,并且我希望对每次传输都有一个响应,以了解是否所有内容都没有问题地发送(并将此调用成功保存到数据库中)。在那里,我在三个电话中只有一次“0”。