file_get_contents()是阻塞函数吗?

时间:2012-11-16 18:30:22

标签: php file-get-contents blocking

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

$resultJSON = FALSE;

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

换句话说:假设API在第3次尝试成功之前失败了两次。我是否发送了3个请求,或者我已经发送了数百个请求,这些请求是否适合3秒窗口?

4 个答案:

答案 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中没有“阻塞”的任何功能。作为替代方案,如果您的服务器允许这样的事情,您可以:

  1. 在等待API调用通过时,使用pcntl_fork()并在脚本中执行其他操作。
  2. 如果exec()不可用,请使用&在后​​台调用另一个脚本[使用pcntl_fork()]为您执行API调用。
  3. 但是,如果您在没有成功调用该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,因为您可以设置更合理的超时值。