4

我正在通过 file_get_contents 连接到不可靠的 API。由于它不可靠,因此我决定将 api 调用放入 while 循环中:

$resultJSON = FALSE;

while(!$resultJSON) {
    $resultJSON = file_get_contents($apiURL);
    set_time_limit(10);
}

换句话说:假设 API 在第 3 次尝试成功之前失败了两次。我发送了 3 个请求,还是发送了数百个请求以适应该 3 秒窗口?

4

4 回答 4

8

file_get_contents(),基本上就像 PHP 中的所有函数一样,是一个阻塞调用。

于 2012-11-16T18:34:02.383 回答
2

是的,它是一个阻塞函数。您还应该检查该值是否专门为“假”。(注意使用 ===,而不是 ==。)最后,你想睡 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);
}
于 2012-11-16T18:34:42.957 回答
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选择。你应该检查出来。

当然,这假设您有可用的 cURL

于 2012-11-16T19:06:57.397 回答
1

我不知道 PHP 中没有“阻塞”的任何函数。作为替代方案,如果您的服务器允许此类操作,您可以:

  1. pcntl_fork()在等待 API 调用通过时,在脚本中使用和执行其他操作。
  2. 如果不可用,用于exec()在后台调用另一个脚本 [使用&] 为您执行 API 调用。pcntl_fork()

但是,如果在没有成功调用该 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,因为您可以设置更合理的超时值。

于 2012-11-16T19:10:38.090 回答