如何加快的file_get_contents?(How to speed up file_get_c

2019-08-03 11:32发布

这里是我的代码:

$language = $_GET['soundtype'];
$word = $_GET['sound'];
$word = urlencode($word);
if ($language == 'english') {
    $url = "<the first url>";
} else if ($language == 'chinese') {
    $url = "<the second url>";
}
$opts = array(
  'http'=>array(
    'method'=>"GET",
    'header'=>"User-Agent: <my user agent>"
  )
);
$context = stream_context_create($opts);
$page = file_get_contents($url, false, $context);
header('Content-Type: audio/mpeg');
echo $page;

但我发现,这种运行非常缓慢。

是否有优化的任何可能的方法呢?

注: $url是远程URL。

Answer 1:

这是因为缓慢file_get_contents()读取整个文件到$page ,PHP等待输出内容之前接收到的文件。 所以,你在做什么是:下载服务器端的整个文件,然后将其输出作为一个巨大的字符串。

file_get_contents()不支持流或抓住远程文件的偏移。 一种选择是创建一个原始套接字fsockopen()执行HTTP请求,并读取一个循环的反应,当你阅读每个大块,它输出到浏览器。 这将是更快,因为该文件将被载入。

从手动例如:

$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {

    header('Content-Type: audio/mpeg');

    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: www.example.com\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}

以上是循环而仍有内容可用时,在每次迭代读取128个字节,然后将其输出到浏览器。 同样的原理会为你做什么工作。 你需要确保你不输出响应HTTP标头,这将是第几行,因为既然你正在做一个原始的请求,你会得到与报头的原始响应包括在内。 如果你输出的响应头,你会最终有一个损坏的文件。



Answer 2:

正如@MrCode解释,先下载文件到您的服务器,然后将它传递给客户当然会招致加倍的下载时间。 如果你想将文件直接传递到客户端,使用readfile

另外,想一想如果你不能简单地将客户端重定向到使用文件的URL header("Location: $url")所以客户端可以直接从源得到的文件。



Answer 3:

相反输出之前下载整个文件,考虑流出来是这样的:

$in = fopen($url, 'rb', false, $context);
$out = fopen('php://output', 'wb');

header('Content-Type: video/mpeg');
stream_copy_to_stream($in, $out);

如果你敢,你甚至可以尝试(但绝对是实验性的):

header('Content-Type: video/mpeg');
copy($url, 'php://output');

另一种选择是使用内部重定向,使您的Web服务器代理为你的请求。 这将腾出PHP做别的事情。 另请参见我的有关X-SENDFILE和朋友后 。



文章来源: How to speed up file_get_contents?