php 更快的替代 file_get_contents()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2662926/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Faster alternative to file_get_contents()
提问by Rob
Currently I'm using file_get_contents() to submit GET data to an array of sites, but upon execution of the page I get this error:
目前我正在使用 file_get_contents() 将 GET 数据提交到一组站点,但是在执行页面时我收到此错误:
Fatal error: Maximum execution time of 30 seconds exceeded
致命错误:超过了最长 30 秒的执行时间
All I really want the script to do is start loading the webpage, and then leave. Each webpage may take up to 5 minutes to load fully, and I don't need it to load fully.
我真正想让脚本做的就是开始加载网页,然后离开。每个网页最多可能需要 5 分钟才能完全加载,而我不需要它来完全加载。
Here is what I currently have:
这是我目前拥有的:
foreach($sites as $s) //Create one line to read from a wide array
{
file_get_contents($s['url']); // Send to the shells
}
EDIT: To clear any confusion, this script is being used to start scripts on other servers, that return no data.
编辑:为了消除任何混淆,此脚本用于在其他服务器上启动脚本,但不返回任何数据。
EDIT: I'm now attempting to use cURL to do the trick, by setting a timeout of one second to make it send the data and then stop. Here is my code:
编辑:我现在正在尝试使用 cURL 来实现这一点,方法是将超时设置为一秒以使其发送数据然后停止。这是我的代码:
$ch = curl_init($s['url']); //load the urls
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); //Only send the data, don't wait.
curl_exec($ch); //Execute
curl_close($ch); //Close it off.
Perhaps I've set the option wrong. I'm looking through some manuals as we speak. Just giving you an update. Thank you all of you that are helping me thus far.
也许我把选项设置错了。我们说话的时候,我正在浏览一些手册。只是给你一个更新。感谢到目前为止帮助我的所有人。
EDIT: Ah, found the problem. I was using CURLOPT_CONNECTTIMEOUT instead of CURLOPT_TIMEOUT. Whoops.
编辑:啊,发现问题了。我使用的是 CURLOPT_CONNECTTIMEOUT 而不是 CURLOPT_TIMEOUT。哎呀。
However now, the scripts aren't triggering. They each use ignore_user_abort(TRUE); so I can't understand the problem
但是现在,脚本没有触发。他们每个人都使用 ignore_user_abort(TRUE); 所以我无法理解这个问题
Hah, scratch that. Works now. Thanks a lot everyone
哈,刮那个。现在工作。非常感谢大家
采纳答案by Franco
There are many ways to solve this.
有很多方法可以解决这个问题。
You could use cURLwith its curl_multi_* functions to execute asynchronously the requests. Or use cURL the common way but using 1 as timeout limit, so it will request and return timeout, but the request will be executed.
您可以使用带有 curl_multi_* 函数的cURL异步执行请求。或者使用 cURL 的常用方式,但使用 1 作为超时限制,因此它会请求并返回超时,但会执行请求。
If you don't have cURL installed, you could continue using file_get_contents but forking processes (not so cool, but works) using something like ZendX_Console_Process_Unixso you avoid the waiting between each request.
如果您没有安装 cURL,您可以继续使用 file_get_contents,但使用ZendX_Console_Process_Unix之类的东西分叉进程(不是很酷,但有效),这样您就可以避免每个请求之间的等待。
回答by Pekka
Re your update that you only need to triggerthe operation:
重新更新您只需要触发操作:
You could try using file_get_contentswith a timeout. This would lead to the remote script being called, but the connection being terminated after n seconds (e.g. 1).
您可以尝试使用file_get_contents超时。这将导致远程脚本被调用,但连接在 n 秒(例如 1)后终止。
If the remote script is configured so it continues to run even if the connection is aborted (in PHP that would be ignore_user_abort), it should work.
如果远程脚本被配置为即使连接被中止它也会继续运行(在 PHP 中是这样ignore_user_abort),它应该可以工作。
Try it out. If it doesn't work, you won't get around increasing your time_limitor using an external executable. But from what you're saying - you just need to make the request - this should work. You could even try to set the timeout to 0but I wouldn't trust that.
试试看。如果它不起作用,您将无法增加time_limit或使用外部可执行文件。但是从您所说的来看-您只需要提出请求-这应该可行。您甚至可以尝试将超时设置为,0但我不相信。
From here:
从这里:
<?php
$ctx = stream_context_create(array(
'http' => array(
'timeout' => 1
)
)
);
file_get_contents("http://example.com/", 0, $ctx);
?>
To be fair, Chris's answer already includes this possibility: curlalso has a timeout switch.
公平地说,克里斯的回答已经包含了这种可能性:curl还有一个超时开关。
回答by Ian B
As Franco mentioned and I'm not sure was picked up on, you specifically want to use the curl_multi functions, not the regular curl ones. This packs multiple curl objects into a curl_multi object and executes them simultaneously, returning (or not, in your case) the responses as they arrive.
正如佛朗哥所提到的,我不确定是否被采纳,您特别想使用 curl_multi 函数,而不是常规的 curl 函数。这将多个 curl 对象打包到 curl_multi 对象中并同时执行它们,在响应到达时返回(或不返回)响应。
Example at http://php.net/curl_multi_init
回答by Your Common Sense
it is not file_get_contents() who consume that much time but network connection itself.
Consider not to submit GET data to an array of sites, but create an rss and let them get RSS data.
消耗那么多时间的不是 file_get_contents() 而是网络连接本身。
考虑不要将 GET 数据提交给一组站点,而是创建一个 rss 并让他们获取 RSS 数据。
回答by aviv
I don't fully understands the meaning behind your script. But here is what you can do:
我不完全理解你的脚本背后的含义。但您可以这样做:
- In order to avoid the fatal error quickly you can just add set_time_limit(120) at the beginning of the file. This will allow the script to run for 2 minutes. Of course you can use any number that you want and 0 for infinite.
- If you just need to call the url and you don't "care" for the result you should use cUrl in asynchronous mode. This case any call to the URL will not wait till it finished. And you can call them all very quickly.
- 为了快速避免致命错误,您只需在文件开头添加 set_time_limit(120) 即可。这将允许脚本运行 2 分钟。当然,您可以使用任何您想要的数字,0 表示无限。
- 如果您只需要调用 url 而您不“关心”结果,您应该在异步模式下使用 cUrl。在这种情况下,对 URL 的任何调用都不会等到它完成。你可以很快地给他们打电话。
BR.
BR。
回答by Marc B
If the remote pages take up to 5 minutes to load, your file_get_contents will sit and wait for that 5 minutes. Is there any way you could modify the remote scripts to fork into a background process and do the heavy processing there? That way your initial hit will return almost immediately, and not have to wait for the startup period.
如果远程页面最多需要 5 分钟加载,您的 file_get_contents 将等待 5 分钟。有什么方法可以修改远程脚本以分叉到后台进程并在那里进行繁重的处理?这样你的初始命中几乎会立即返回,而不必等待启动期。
Another possibility is to investigate if a HEAD request would do the trick. HEAD does not return any data, just headers, so it may be enough to trigger the remote jobs and not wait for the full output.
另一种可能性是调查 HEAD 请求是否可以解决问题。HEAD 不返回任何数据,只返回标题,因此它可能足以触发远程作业而不是等待完整的输出。

