file_get_contents()是否具有超时设置?


152

file_get_contents()在循环中使用该方法调用一系列链接。每个链接可能需要超过15分钟的处理时间。现在,我担心PHP是否file_get_contents()有超时期限?

如果是,它将因通话超时而移至下一个链接。我不想在没有前一个链接完成的情况下调用下一个链接。

所以,请告诉我是否file_get_contents()有超时时间。包含的文件file_get_contents()设置为set_time_limit()为零(无限制)。



我在使用PHP工具进行Visual Studio扩展的Visual Studio PHP项目中遇到了相同的行为(在同一“服务器”上查询URL时超时)。更多信息在这里
Uwe Keim

使用内置PHP服务器在同一网站上查询URL时也会发生这种情况,因为它是单线程Web服务器。
Uwe Keim

Answers:


297

默认超时由default_socket_timeoutini-setting定义,为60秒。您还可以随时更改它:

ini_set('default_socket_timeout', 900); // 900 Seconds = 15 Minutes

设置超时的另一种方法是将超时stream_context_create设置为正在使用的HTTP流包装的HTTP上下文选项

$ctx = stream_context_create(array('http'=>
    array(
        'timeout' => 1200,  //1200 Seconds is 20 Minutes
    )
));

echo file_get_contents('http://example.com/', false, $ctx);

8
您能否提供有关如何为https url设置超时的信息?
Vinay

11
这东西不能很好地工作,如果您的值是1200,实际上是2400。我只是测试一下。
TomSawyer

15
default_socket_timeout,stream_set_timeout和stream_context_create超时都是每行读/写的超时,而不是整个连接超时。
diyism

32

正如@diyism所说,“ default_socket_timeout,stream_set_timeout和stream_context_create超时都是每行读/写的超时,而不是整个连接超时。 ” @stewe的最高答案使我失败了。

作为使用的替代方法file_get_contents,您始终可以使用curl超时。

因此,这是一个用于调用链接的工作代码。

$url='http://example.com/';
$ch=curl_init();
$timeout=5;

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);

$result=curl_exec($ch);
curl_close($ch);
echo $result;

1
此答案提供了另一种控制连接超时的方法(使用fsockopen代替curl):stackoverflow.com/a/3690321/1869825
stevo 2015年

2
您应该同时在curl中设置CURLOPT_CONNECTTIMEOUT和CURLOPT_TIMEOUT。请参阅stackoverflow.com/a/27776164/1863432
bhelm '16

2
不是有效的响应,问题是“ file_get_contents”。响应很好,但是不恰当。
e-info128

8

是! 通过在第三个参数中传递流上下文

这里的超时为1s

file_get_contents("https://abcedef.com", 0, stream_context_create(["http"=>["timeout"=>1]]));

https://www.php.net/manual/zh/function.file-get-contents.php的注释部分中的源

HTTP上下文选项

method
header
user_agent
content
request_fulluri
follow_location
max_redirects
protocol_version
timeout

其他环境: https : //www.php.net/manual/en/context.php


1
286代表的答案无效,但您的答案有效:)
VE7JRO

给出的超时stream_context_create仅适用于连接超时。如果服务器在给定的超时时间内答复(发送了一些数据),但花了很长时间才发送剩余的有效负载,则此超时不会中断慢速传输。
z80crew

6

值得注意的是,如果即时更改default_socket_timeout,在file_get_contents调用之后恢复其值可能会很有用:

$default_socket_timeout = ini_get('default_socket_timeout');
....
ini_set('default_socket_timeout', 10);
file_get_contents($url);
...
ini_set('default_socket_timeout', $default_socket_timeout);

1
但您知道ini_set不会永久设置事物,对吗?所以基本上您脚本的四分之二是无用的
Flash Thunder

2
@FlashThunder如果稍后需要先前超时的代码中还有另一个file_get_contents调用,则不会。通常,在执行特定代码后立即恢复设置更改以更改特定代码位的设置。
Leigh Bicknell,

1
@FlashThunder是一个好习惯,在调用后恢复socket_timeout值,以便在同一脚本执行中对同一函数的后续调用使用全局设置。
Pascal Roget

1

当我在主机中更改php.ini时,对我来说工作:

; Default timeout for socket based streams (seconds)
default_socket_timeout = 300
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.