Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用完整url时,PHP文件获取内容的速度非常慢_Php - Fatal编程技术网

使用完整url时,PHP文件获取内容的速度非常慢

使用完整url时,PHP文件获取内容的速度非常慢,php,Php,我正在使用一个从HTML页面生成pdf文件的脚本(最初不是我创建的)。问题是现在需要很长的时间,比如1-2分钟来处理。据推测,这原本运行良好,但在过去几周内已经放缓 该脚本在php脚本上调用file\u get\u contents,然后将结果输出到服务器上的HTML文件中,并在该文件上运行pdf生成器应用程序 我似乎已将问题缩小到对完整url而不是本地路径的file\u get\u contents调用 当我使用 $content = file_get_contents('test.txt')

我正在使用一个从HTML页面生成pdf文件的脚本(最初不是我创建的)。问题是现在需要很长的时间,比如1-2分钟来处理。据推测,这原本运行良好,但在过去几周内已经放缓

该脚本在php脚本上调用
file\u get\u contents
,然后将结果输出到服务器上的HTML文件中,并在该文件上运行pdf生成器应用程序

我似乎已将问题缩小到对完整url而不是本地路径的
file\u get\u contents
调用

当我使用

$content = file_get_contents('test.txt');
它几乎是瞬间处理的。但是,如果我使用完整的url

$content = file_get_contents('http://example.com/test.txt');
处理过程需要30-90秒

它不仅限于我们的服务器,在访问任何外部url(例如)时速度都很慢。我相信这个脚本调用了完整的url,因为如果您在本地调用该文件,就需要一些查询字符串变量,但这些变量不起作用


我还试过
fopen
readfile
curl
,它们都同样慢。有什么办法可以解决这个问题吗?

你能试着在服务器上从命令行获取这个url吗?我想到了卷发或wget。如果这些人以正常速度检索URL,那么这不是网络问题,很可能是apache/php设置中的问题。

我会用它来获取外部内容,因为这比
file\u get\u contents
方法快得多。不确定这是否能解决问题,但值得一试

还要注意,服务器速度会影响检索文件所需的时间

下面是一个用法示例:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://example.com/test.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
注意:这已在PHP 5.6.14中修复。即使是HTTP/1.0请求,现在也会自动发送
连接:close

我花了很长时间才弄清楚文件获取内容脚本缓慢的原因

通过使用Wireshark进行分析,问题(在我的情况下,也可能是你的情况下)是远程web服务器直到15秒才关闭TCP连接(即“保持活动”)

事实上,file_get_contents不会发送“connection”HTTP头,因此远程web服务器默认认为这是一个保持活动的连接,并且在15秒之前不会关闭TCP流(这可能不是标准值-取决于服务器配置)

如果HTTP有效负载长度达到响应内容长度HTTP报头中指定的长度,则正常浏览器会考虑页面被完全加载。文件内容不能做到这一点,这太可惜了

解决方案

因此,如果您想了解解决方案,请参见:

$context = stream_context_create(array('http' => array('header'=>'Connection: close\r\n')));
file_get_contents("http://www.something.com/somepage.html",false,$context);

下载完成后,只需告诉远程web服务器关闭连接,因为文件获取内容本身不够智能,无法使用响应内容长度HTTP头完成连接。

有时,这是因为服务器上的DNS速度太慢,请尝试以下操作:

替换

echo file_get_contents('http://www.google.com');
作为

我也有同样的问题

唯一对我有效的方法是在
$options
数组中设置超时

$options = array(
    'http' => array(
        'header'  => implode($headers, "\r\n"),
        'method'  => 'POST',
        'content' => '',
        'timeout' => .5
    ),
);
时间:50976 ms(平均时间总共5次尝试)

时间:46679 ms(平均时间总共5次尝试)


注意:request.php用于从mysql数据库中获取一些数据。

我有一个通过API传递的巨大数据,我正在使用
file\u get\u contents
读取数据,但大约需要60秒。然而,使用KrisWebDev的解决方案大约需要25秒

$context = stream_context_create(array('https' => array('header'=>'Connection: close\r\n')));
file_get_contents($url,false,$context);

我也将用CURL来考虑,你可以“线程”请求。这对我帮助很大,因为我目前还没有访问到允许线程的PHP版本

例如,我使用file_get_内容从远程服务器获取7个图像,每个请求需要2-5秒。在用户等待生成PDF时,仅此过程就向过程中添加了30秒或其他时间

这实际上将时间减少到大约1张图像。另一个例子是,我在之前验证36个URL所用的时间。我想你明白了。:-)

然后关闭文件:

    curl_multi_close($master);

我知道这是一个老问题,但我今天发现了,答案对我来说并不适用。我没有看到有人说每个IP的最大连接数可以设置为1。这样,您正在执行API请求,而API正在执行另一个请求,因为您使用了完整的url。这就是直接从光盘加载的原因。对我来说,这解决了一个问题:

if (strpos($file->url, env('APP_URL')) === 0) {
    $url = substr($file->url, strlen(env('APP_URL')));
} else {
    $url = $file->url;
}
return file_get_contents($url);

当我从命令行尝试wget时,速度也非常慢。它挂在墙上。。。步服务器上可能存在某种DNS问题。尝试使用“主机”或“nslookup”(任何可用的)并尝试从系统中解析各种不同的主机名。你能链接到一个关于比较文件内容和卷曲速度的基准吗?@shamittomar,基准各不相同,但一个简单的谷歌可以得出一系列不同的结果。是其中之一。我只知道,在我过去使用过的各种应用程序中,cURL的速度更快。这仅仅是个人的经验,因为cURL的开发是为了获取远程文件。其中as file_get_contents/fopen是为一般读取本地文件而开发的。curl的一个优点是它将重用现有的连接(当使用相同的句柄时),这一点很重要,如果您对单个主机执行多个请求(例如API调用)。我在API测试路由上执行get(无数据库连接或文件系统交互),只需从
文件获取内容
切换到
curl
即可将响应时间从约500毫秒缩短到约100毫秒。感谢您,这是一款超级甜蜜的产品。已被接受、镀金、装框并广受欢迎。非常感谢。这可以从somepage.html方面完成吗?(如果somepage.html是一个php脚本,它可以
$context = stream_context_create(array('https' => array('header'=>'Connection: close\r\n')));
file_get_contents($url,false,$context);
    $timeout = 30;
    $retTxfr = 1;
    $user = '';
    $pass = '';

    $master = curl_multi_init();
    $node_count = count($curlList);
    $keys = array("url");

    for ($i = 0; $i < $node_count; $i++) {
        foreach ($keys as $key) {
            if (empty($curlList[$i][$key])) continue;
            $ch[$i][$key] = curl_init($curlList[$i][$key]);
            curl_setopt($ch[$i][$key], CURLOPT_TIMEOUT, $timeout); // -- timeout after X seconds
            curl_setopt($ch[$i][$key], CURLOPT_RETURNTRANSFER, $retTxfr);
            curl_setopt($ch[$i][$key], CURLOPT_HTTPAUTH, CURLAUTH_ANY);
            curl_setopt($ch[$i][$key], CURLOPT_USERPWD, "{$user}:{$pass}");
            curl_setopt($ch[$i][$key], CURLOPT_RETURNTRANSFER, true);
            curl_multi_add_handle($master, $ch[$i][$key]);
        }
    }

    // -- get all requests at once, finish when done or timeout met --
    do {  curl_multi_exec($master, $running);  }
    while ($running > 0);
            if ((int)curl_getinfo($ch[$i][$key], CURLINFO_HTTP_CODE) > 399 || empty($results[$i][$key])) {
                unset($results[$i][$key]);
            } else {
                $results[$i]["options"] = $curlList[$i]["options"];
            }
            curl_multi_remove_handle($master, $ch[$i][$key]);
            curl_close($ch[$i][$key]);
    curl_multi_close($master);
if (strpos($file->url, env('APP_URL')) === 0) {
    $url = substr($file->url, strlen(env('APP_URL')));
} else {
    $url = $file->url;
}
return file_get_contents($url);