dongzaobei0942
2013-09-11 11:04 阅读 127
已采纳

文件获取内容或fsockopen - 超时问题

I have a php file called testResponse.php which is only :

<?php
 sleep(5);
 echo"go";
?>

Now, I'm calling this file from a another page using file_get_contents like this :

$start= microtime(true);
$opts = array('http' =>
    array(
        'method'  => 'GET',
        'timeout' => 1
    )
);

$context  = stream_context_create($opts);

$loc = @file_get_contents("http://www.mywebsite.com/testResponse.php", false, $context);
$end= microtime(true);
echo $end - $start, "
";

The output is more than 5 sec, which means that my timeout has been ignored... I followed the advice of this post : stackoverflow.com/questions/3689371

But it seems that hostname cannot be a path (like www.mywebsite.com/testResponse.php) but directly the hostname like www.mywebsite.com.

So I'm stuck to achieve this goal :

Get content of page www.test.com/x.php with constraint :

  • if test.com doesn't exist or the page x.php doesn't exist returns nothing quickly
  • if the page exist but takes more than 1 sec to load, abort
  • else get the content of the file

Edit : By the way, it seems to work when I call this page (testResponse.php) from my local server. Well, it multiply the timeout by 2. For instance, If I have 1 for timeout, I will have echoed something like "2.0054645". But only from local...

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

1条回答 默认 最新

  • 已采纳
    dongshuofu0039 dongshuofu0039 2013-09-18 15:41

    The solution is to use PHP's cURL functions. The other question you linked to explains things properly, about the read timeouts vs. the connection timeouts, and so on, but neither of those are truly what you're looking for here. Even the connection timeout won't work, because the connection to testResponse.php is always successful; after that it's waiting, so what you need is an execution timeout. This is where cURL comes in handy.

    So, testResponse.php doesn't need to be altered. In your main file, though, try the following code (this is tested and it works on my server):

    $start = microtime(true);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://www.mywebsite.com/testResponse.php");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 1);
    $output = curl_exec($ch);
    $errno = curl_errno($ch);
    if ($errno > 0) {
        if ($errno === 28) {
            echo "Connection timed out.";
        }
        else {
            echo "Error #" . $errno . ": " . curl_error($ch);
        }
    }
    else {
        echo $output;
    }
    $end = microtime(true);
    echo "<br><br>" . ($end - $start);
    curl_close($ch);
    

    This sets the execution time of the cURL session, via the CURLOPT_TIMEOUT option you see on line 5. So, when the connection is timed out, $errno will equal 28, the code for cURL's operation timeout error. The rest of the error codes are listed in the cURL documentation, so you can expand the script above to act accordingly.

    Finally, because of the CURLOPT_RETURNTRANSFER option that's set, curl_exec($ch) will be set to the content of the retrieved page if the session succeeds. Otherwise, it will equal false.

    Hope this helps!

    Edit: Removed the statement setting CURLOPT_HEADER. I also, for some reason, was under the impression that curl_exec($ch) set the value of $ch to the returned contents, forgetting that the contents are returned by curl_exec().

    点赞 9 评论 复制链接分享

相关推荐