我正在通过file_get_contents连接到一个不可靠的API。 既然它是不可靠的,我决定将api调用放入一个while循环中:
$resultJSON = FALSE;
while(!$resultJSON) {
$resultJSON = file_get_contents($apiURL);
set_time_limit(10);
}
换句话说:如果API在第三次尝试成功之前失败了两次,我是发送了3个请求,还是在那个3秒的时间窗口内发送了数百个请求?
我正在通过file_get_contents连接到一个不可靠的API。 既然它是不可靠的,我决定将api调用放入一个while循环中:
$resultJSON = FALSE;
while(!$resultJSON) {
$resultJSON = file_get_contents($apiURL);
set_time_limit(10);
}
file_get_contents()
,就像 PHP 中的基本所有函数一样,是一个阻塞调用。
file_get_contents
是 fopen/fread/fclose
的缩写,同时支持 URL。但这不是 PHP 读取 URL 的唯一方式(不使用 cURL 等)。可以通过 fsockopen
、STREAM_CLIENT_ASYNC_CONNECT
和/或 stream_set_blocking
实现非阻塞模式。你的回答没有问题,我只是说一下。干杯! - Dejan Marjanović是的,它是一个阻塞函数。您还应该检查值是否特别为“false”。(请注意使用===而不是==。)最后,您需要休眠10秒钟。set_time_limit()用于设置在自动终止之前的最大执行时间。
set_time_limit(300); //Run for up to 5 minutes.
$resultJSON = false;
while($resultJSON === false)
{
$resultJSON = file_get_contents($apiURL);
sleep(10);
}
在 @Sammitch 建议使用 cURL 而不是 file_get_contents()
的基础上进行扩展:
<?php
$apiURL = 'http://stackoverflow.com/';
$curlh = curl_init($apiURL);
// Use === not ==
// if ($curlh === FALSE) handle error;
curl_setopt($curlh, CURLOPT_FOLLOWLOCATION, TRUE); // maybe, up to you
curl_setopt($curlh, CURLOPT_HEADER, FALSE); // or TRUE, according to your needs
curl_setopt($curlh, CURLOPT_RETURNTRANSFER, TRUE);
// set your timeout in seconds here
curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curlh, CURLOPT_TIMEOUT, 30);
$resultJSON = curl_exec($curlh);
curl_close($curlh);
// if ($resultJSON === FALSE) handle error;
echo "$resultJSON\n"; // Now process $resultJSON
?>
还有很多 curl_setopt
选项。你应该去查看一下。
当然,这假设 你已经安装了 cURL。
我不知道PHP中是否有任何不会“阻塞”的函数。作为替代方案,如果您的服务器允许这样做,您可以:
pcntl_fork()
在等待API调用完成时在脚本中执行其他操作。pcntl_fork()
,则使用exec()
在后台调用另一个脚本[使用&
]来为您执行API调用。但是,如果您的脚本没有成功调用该API就不能执行任何其他操作,那么该调用是否“阻塞”并不重要。您真正需要关注的是等待此API所花费的时间是否超过了配置的max_execution_time
,导致您的脚本在中途被中止而未能正确完成。
$max_calls = 5;
for( $i=1; $i<=$max_calls; $i++ ) {
$resultJSON = file_get_contents($apiURL);
if( $resultJSON !== false ) {
break;
} else if( $i = $max_calls ) {
throw new Exception("Could not reach API within $max_calls requests.");
}
usleep(250000); //wait 250ms between attempts
}
file_get_contents()
默认超时时间为60秒,因此您的脚本很可能会被终止。强烈考虑改用cURL,因为您可以设置更合理的超时值。
set_time_limit
的一个打字错误。(PHP内置函数。) - user149341set_time_limit(10)
的意思是,“如果你在这个 while 循环中仍然卡住了超过 10 秒,就放弃执行。” - patricksayshifile_get_contents()
通常是一个非常糟糕的想法。在您的情况下,您应该使用cURL和一个或多个超时选项。 - Sammitchfile_get_contents()
在处理URL时有什么问题。 - patricksayshi