PHP的file_get_contents函数忽略超时问题?

15
$url = 'http://a.url/i-know-is-down';

//ini_set('default_socket_timeout', 5);

$ctx = stream_context_create(array(
    'http' => array(
        'timeout' => 5,
        'ignore_errors' => true
        )
    )
);

$start = microtime(true);
$content = @file_get_contents($url, false, $ctx);
$end = microtime(true);
echo $end - $start, "\n";

我通常获得的响应时间为21.232秒,这不应该是大约5秒钟吗?

取消注释 ini_set 行并没有帮助。


你能否尝试关闭"ignore_errors"标志以及静默的@file_get_contents()调用,看看是否会出现明显的错误? - Mahdi.Montgomery
@Mahdi.M:我不能关闭ingnore_errors,因为我需要区分诸如404错误和由连接问题生成的错误。让我重新表述一下。如果ingnore_errors关闭,并且服务器返回404,则$content将为false,我需要知道$content是否为false是因为404错误还是因为连接错误。当我禁用@操作符时显示的错误是通用的,例如“file_get_contents(filename):无法打开流”。 - Cesar
2
作为一个经验法则,你不应该需要使用 @ 符号。如果它对你的应用程序至关重要,那么你很可能是在错误的方式下编写它。并非总是如此,但通常情况下是这样的! - Rich Bradshaw
@Cesar:如果你需要区分HTTP错误码,请在调用file_get_contents()后读取$http_response_header。它将以由服务器返回的HTTP标头的数组形式被填充。你可以获取除了服务器连接问题(比如找不到服务器,超时,拒绝连接等)之外的所有错误。 - MestreLion
1个回答

15

你正在使用 socket_create_context 设置 读取 超时时间。如果你要访问的 页面 不存在,那么服务器将允许你连接并返回 404 错误。然而,如果 网站 不存在(无法解析或者没有网页服务器),那么 file_get_contents() 将忽略读取超时时间,因为它甚至还没有连接到该网站。

我认为你不能在 file_get_contents 中设置连接超时时间。最近,我重写了一些代码,使用 fsockopen() 来指定连接超时时间

$connTimeout = 30 ;
$fp = fsockopen($hostname, $port, $errno, $errstr, $connTimeout);

当然,使用fsockopen将需要您在循环中使用fread(),这会使您的代码稍微变得复杂。但是,它确实可以让您更好地控制使用stream_get_meta_data()在读取时检测读取超时。

http://php.net/stream_get_meta_data


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接