file_get_contents() 是不是有超时设置?

Posted

技术标签:

【中文标题】file_get_contents() 是不是有超时设置?【英文标题】:Does file_get_contents() have a timeout setting?file_get_contents() 是否有超时设置? 【发布时间】:2012-05-01 10:40:54 【问题描述】:

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

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

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

【问题讨论】:

交叉引用:Handling delays when retrieving files from remote server in PHP 我在使用 PHP Tools for Visual Studio 扩展的 Visual Studio PHP 项目中遇到了相同的行为(在同一“服务器”上查询 URL 时超时)。 More information here. 在使用built-in PHP server to query an URL on the same website 时也会发生这种情况,因为它是单线程网络服务器。 gist.github.com/sabarasaba/1387550 【参考方案1】:

默认超时由default_socket_timeout ini-setting 定义,即 60 秒。您也可以随时更改它:

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

另一种设置超时的方法是使用stream_context_create 将超时设置为HTTP context options 的HTTP context options 在使用中:

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

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

【讨论】:

您能否提供有关如何为 https url 设置超时的信息? 这个东西不完美,如果你的值是1200,它实际上是2400。我只是测试一下。 default_socket_timeout、stream_set_timeout、stream_context_create timeout都是每行读/写的超时时间,不是整个连接超时时间。【参考方案2】:

正如@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;

【讨论】:

这个答案提供了另一种控制连接超时的方法(使用fsockopen 而不是curl):***.com/a/3690321/1869825 你应该在 curl 中同时设置 CURLOPT_CONNECTTIMEOUT 和 CURLOPT_TIMEOUT。见***.com/a/27776164/1863432 不是有效响应,问题是针对“file_get_contents”的。反应很好,但不恰当。【参考方案3】:

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

; Default timeout for socket based streams (seconds)
default_socket_timeout = 300

【讨论】:

【参考方案4】:

值得注意的是,如果动态更改 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);

【讨论】:

但您知道 ini_set 不会永久设置这些东西,对吧?所以基本上你脚本的 4 半是没用的 @FlashThunder 如果代码中稍后有另一个对 file_get_contents 的调用需要先前的超时,则不会。在特定代码执行后恢复动态更改的设置通常是一种很好的做法。 @FlashThunder 在调用后恢复 socket_timeout 值是一种很好的做法,以便对同一函数的后续调用在同一脚本执行中使用全局设置。 改用ini_restore('default_socket_timeout');不是更好吗? php.net/manual/en/function.ini-restore.php【参考方案5】:

是的!通过在第三个参数中传递stream context:

此处超时1s

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

来源https://www.php.net/manual/en/function.file-get-contents.php评论区

HTTP context options:

method
header
user_agent
content
request_fulluri
follow_location
max_redirects
protocol_version
timeout

Non HTTP stream contexts

Socket
FTP
SSL
CURL
Phar
Context (notifications callback)
Zip

【讨论】:

286 rep 的答案无效,但你的答案有效 :) stream_context_create 中给出的超时仅适用于连接超时。如果服务器在给定的超时时间内回复(发送一些数据),但需要永远发送其余的有效负载,则此超时不会中断慢速传输。【参考方案6】:

对于原型设计,使用带有 -m 参数的 shell 中的 curl 允许传递毫秒,并且在两种情况下都可以工作,或者连接没有启动,错误 404、500,错误的 url,或者整个数据被'未在允许的时间范围内全部检索,超时始终有效。 Php 永远不会闲逛

不要在 shell 调用中传递未经处理的用户数据。

system("curl -m 50 -X GET 'https://api.kraken.com/0/public/OHLC?pair=LTCUSDT&interval=60' -H  'accept: application/json' > data.json");
// This data had been refreshed in less than 50ms
var_dump(json_decode(file_get_contents("data.json"),true));

【讨论】:

永远不要那样做。除了打开一堆潜在的安全漏洞,根据上下文,你在每个 PHP 安装中都有一个完整的 curl API。 多年来我一直为我的个人脚本这样做,这从未引起问题。关键部分是-m 参数。安全漏洞,仅在使用未经处理的用户数据时,如警告。顺便说一句,这是唯一一个完全适用于所有这些答案的班轮。再读一遍。 PHP 不像你所相信的那样内置 curl,你必须安装单独的包 php-curl。但是 shell curl 总是可用的。 问这个问题的人的 PHP 环境确实有可用的 libcurl,任何可能不需要的人都不需要问这个问题。使用这样的 shell 执行是你写东西的最肮脏的方式。 我不认为它是,有时使用shell是访问第三方模块/程序的唯一方法。

以上是关于file_get_contents() 是不是有超时设置?的主要内容,如果未能解决你的问题,请参考以下文章

file_get_contents() 从 url 而不是 json 返回原始数据 [重复]

Python Pandas str.contains() 行中带有超链接

如果有超链接,则更改列表样式类型 - 没有 javascript/jQuery [重复]

如果有超链接,则更改列表样式类型 - 没有 javascript/jQuery [重复]

url 不存在时的 file_get_contents

readfile & file_get_contents异同