dongzaobei0942 2013-09-11 11:04
浏览 237
已采纳

文件获取内容或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 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().

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效