【问题标题】:Download File From Url Using file_get_contents and file_put_contents使用 file_get_contents 和 file_put_contents 从 URL 下载文件
【发布时间】:2015-09-12 21:04:32
【问题描述】:

我尝试从此网址下载视频文件

<div style="overflow:scroll;">
https://r10---sn-a5m7znee.googlevideo.com/videoplayback?upn=wWztkINP-Nk&source=youtube&key=yt5&mime=video%2F3gpp&requiressl=yes&initcwndbps=13662500&fexp=9407478%2C9408710%2C9409069%2C9415365%2C9415485%2C9416023%2C9416126%2C9417707%2C9418153%2C9418448%2C9420348&pl=36&sparams=dur%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csource%2Cupn%2Cexpire&mv=m&mt=1442090500&ms=au&ip=2602%3Affea%3A1001%3Aa60%3A%3A8673&id=o-AEiN5gMiULrH4nyZFXgNMByrHGr26gVlBZ74tMKtCqBy&lmt=1421779843167082&expire=1442112121&dur=249.382&mn=sn-a5m7znee&mm=31&ipbits=0&sver=3&itag=17&title=Ellie+Goulding+-+Love+Me+Like+You+Do+%28Official+Video%29&keepalive=no&ratebypass=yes&signature=1255578EB41863E01DDD70B56B15956BECDB7B55.336CEDA1BACCDBB8258B2A717E7C487D459F2C98
</div>

用这个脚本

file_put_contents('video.mp4', file_get_contents($the_link));


但我无法获取文件,我尝试了带有一些 url 的脚本,但结果不同
当我使用 Internet 下载管理器下载 url 时,有一条通知说服务器发送了以下名称“file_name”
任何解决方案?
谢谢

【问题讨论】:

  • 您需要特定设置以允许使用file_get_contents 下载网址。这是一个常见问题,建议您浏览 Stack Overflow 了解如何更改设置以及在file_get_contents 失败时如何获取相关错误信息。

标签: php url download


【解决方案1】:

这是一个示例脚本,它使用 file_get_contentsfile_put_contents 从 URI 下载 .zip 文件

<?php

class DownloadZippedFile
{

    public function __construct()
    {
        ;
    }

    public function downloadZippedFile($uri, $fileName)
    {
        $opts = [
            'http' => [
                'method'  => 'GET',
                'header'  => '',
                'follow_location' => 0,
                'request_fulluri' => true,
                'protocol_version' => 1.1,
                'user-agent' => 'Paw/3.1.5 (Macintosh; OS X/10.13.2) GCDHTTPRequest',
                'content' => '',
                'connection' => 'close',
            ],
        ];

        $context = stream_context_create($opts);

        $result = file_get_contents($uri, false, $context);

        // search for a 301, 302 in the $http_response_header array
        if ( stristr($http_response_header[0], 'HTTP/1.1 301') ||
            stristr($http_response_header[0], 'HTTP/1.1 302'))
        {
            // find the location to redirect to
            foreach ($http_response_header as $intIndex => $header) {
                if (strstr($header, 'Location: ')) {
                    // get the location to redirect to by splitting on the space
                    $locationArray = explode(' ', $header);
                    $uri = $locationArray[1];
                }
            }

            # attempt the request again
            file_put_contents($fileName, file_get_contents($uri, false, $context));
        }

        file_put_contents($fileName, file_get_contents($uri, false, $context));
    }
}

function main()
{
    $documentId = '603411390';
    $uri = 'http://mis.ercot.com/misdownload/servlets/mirDownload?doclookupId='.$documentId;
    $fileName = './downloads/'.$documentId.'.zip';

    $downloader = new DownloadZippedFile();
    $downloader->downloadZippedFile($uri, $fileName);
}

main();

使用 PHP 的 file_get_contentsfile_put_contents 的好处是它们不依赖任何第三方库(例如 cURL),并且可以与不同版本的 PHP 一起使用

虽然 cURL 可以工作,但过去使用 cURL 的 PHP 方法发生了变化,因此您必须跟上 PHP 版本的变化。

如果内存是个问题,那么使用这个公认的答案Download Large Files Efficiently

【讨论】:

  • 不要将人们与虚假声明和您的主观偏好相混淆。第一的。 CURL API 多年来没有改变,甚至 2008 年编写的代码也能像以前一样正常工作。它也更具可配置性和可调试性。第二。通过 CURL 和通过 file_getcontents+file_put_contents 下载文件之间存在巨大差异。 file_get_contents 会将整个文件加载到 RAM 中,而 file_put_contents 将保留 RAM 的重要部分用于写入缓冲区。虽然 curl(正确配置)会将文件直接流式传输到磁盘。
  • 这不是主观的。如果您从源代码编译 PHP,则 2 年的变化打破了如何发送带有正文的请求。我发现“file_get_contents”解决了我的问题,而不是尝试拥有 2 个单独的 cURL 版本。其次,从 PHP 5.5 到 PHP7,cURL 函数发生了一些重大变化。因此,如果/当 PHP 决定进行更改时,OP 将不得不更新代码。最后,我们不知道 OP 是否需要低内存配置,所以我建议的方法没有问题
  • 考虑到问题和 OP 配置文件,我做出了假设(就像您所做的那样),OP 并没有经验丰富,无法看到不同方法的细微差别和差异。因此,即使有人询问 file_get_contents,也可以提供有用的建议。出于同样的原因,我怀疑他会编译 PHP。如果您打算从 YT 下载视频,内存消耗是一个问题。如果它对您有用,则仅意味着它对您有用,仅此而已。中断更改是什么意思?你有一个例子吗?我链接到的示例对您不起作用吗?
  • @Andrew 我没有手头的例子,但是在 PHP.net 上的快速搜索显示 CURLOPT_PROGRESSFUNCTIONCURLOPT_NOPROGRESS 从 5.5 更改为 5.6 并破坏了一些东西。几年前我遇到的问题是 cURL 没有正确发送 HTTP 正文的问题。它已修复,但几天后。人们编译 PHP 并不少见,尤其是使用 FreeBSD 端口和 Crux,它们都编译源代码。我更新了我的答案,听起来不那么偏向 cURL
【解决方案2】:

首先检查this sample 代码并尽可能使用curl 而不是file_get_contents

其次 - 谷歌不喜欢有人直接下载他们的内容。因此,您可能需要通过添加常规浏览器请求中的“正常”标头来假装真正的浏览器。

【讨论】:

  • 当我使用 IDM 下载 url 时,服务器会发送以下名称“file_name”
  • OP 要求提供file_get_contentsfile_put_contents。不要建议他/她的 PHP 版本可能可能不支持的第 3 方库。此外,cURL 要求 OP 不断了解 cURL 更新,并在更新可用时修补他/她的 PHP 版本。
猜你喜欢
  • 2014-09-24
  • 1970-01-01
  • 2013-02-15
  • 2016-03-21
  • 2019-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多