我通过file_get_contents连接到不可靠的API。由于它不可靠,我决定将api调用放入while循环中:
$resultJSON = FALSE;
while(!$resultJSON) {
$resultJSON = file_get_contents($apiURL);
set_time_limit(10);
}
换句话说:假设API在第3次尝试成功之前失败了两次。我是否发送了3个请求,或者我已经发送了数百个请求,这些请求是否适合3秒窗口?
答案 0 :(得分:8)
file_get_contents()
,就像PHP中的所有函数一样,是一个阻塞调用。
答案 1 :(得分:2)
是的,这是一个阻止功能。您还应该检查该值是否明确为“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);
}
答案 2 :(得分:1)
扩展@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
个选项。 You should check them out.
当然,这假定为you have cURL available。
答案 3 :(得分:1)
我不知道PHP中没有“阻塞”的任何功能。作为替代方案,如果您的服务器允许这样的事情,您可以:
pcntl_fork()
并在脚本中执行其他操作。exec()
不可用,请使用&
在后台调用另一个脚本[使用pcntl_fork()
]为您执行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()
has a default timeout of 60 seconds所以你真的有被杀剧本的危险。请认真考虑使用cURL,因为您可以设置更合理的超时值。