【问题标题】:Can't get remote filename to file_get_contents() and then store file无法将远程文件名获取到 file_get_contents() 然后存储文件
【发布时间】:2012-08-07 09:13:14
【问题描述】:

我想下载一个远程文件并将其放在我的服务器目录中,并与原始文件具有相同的名称。我尝试使用file_get_contents($url)

问题是文件名不包含在$url 中,就像:www.domain.com?download=1726。这个网址给我,例如:myfile.exe,所以我想用file_put_contents('mydir/myfile.exe');

如何检索文件名?下载前我试过get_headers(),但我只有文件大小、修改日期等信息,文件名不见了。

【问题讨论】:

标签: php file header file-get-contents remote-server


【解决方案1】:

我用另一种方式解决了它。我发现如果 url 标头中没有 content-disposition ,则 URL 中存在文件名。因此,此代码适用于任何类型的 URL(不需要 cURL):

$url = "http://www.example.com/download.php?id=123";
// $url = "http://www.example.com/myfile.exe?par1=xxx";
$content = get_headers($url,1);
$content = array_change_key_case($content, CASE_LOWER);

    // by header
if ($content['content-disposition']) {
    $tmp_name = explode('=', $content['content-disposition']);
    if ($tmp_name[1]) $realfilename = trim($tmp_name[1],'";\'');
} else  

// by URL Basename
{
    $stripped_url = preg_replace('/\\?.*/', '', $url);
    $realfilename = basename($stripped_url);

} 

有效! :)

【讨论】:

  • +1 。它非常有用,但你为什么不接受它作为答案呢?这段代码有问题吗?
【解决方案2】:

基于 Peter222 的代码,我编写了一个函数来获取文件名。 您可以使用 $http_response_header 变量:

function get_real_filename($headers,$url)
{
    foreach($headers as $header)
    {
        if (strpos(strtolower($header),'content-disposition') !== false)
        {
            $tmp_name = explode('=', $header);
            if ($tmp_name[1]) return trim($tmp_name[1],'";\'');
        }
    }

    $stripped_url = preg_replace('/\\?.*/', '', $url);
    return basename($stripped_url);
}

用法:($http_response_header 将由 file_get_contents() 填充)

$url = 'http://example.com/test.zip';
$myfile = file_get_contents($url);
$filename = get_real_filename($http_response_header,$url)

【讨论】:

    【解决方案3】:

    file_get_contents() 如果文件已被网络服务器预先解析,则通过 HTTP 包装器不会直接下载文件。

    举个例子:如果你在一个删除网页(example.com/foobar.php)上调用file_get_contents(),你将不会看到foobar.php源代码,但是webserver如何example.com 解析 PHP 文件。因此,您将只能检索生成的 HTML 输出。

    如果 URL 中不存在文件名,并且您无法从任何地方获取它,那么您就陷入了死胡同。数据不能只是从数据的超越领域召唤

    对于替代解决方案,我只能建议使用cURL 库(它用于处理从您的服务器(因为它是客户端)到使用 URL 的其他服务器的查询,因此名称 cient URL) 或file sockets。这是another question's answer on Stack Overflow,它描述了如何使用cURL 获取文件名。

    另外,您可以尝试与 domain.com 的管理员/维护者/网站管理员团队联系,询问他们是否有公开可用的 API 来获取文件名和其他元数据。

    【讨论】:

    • 感谢您的快速回复。我会尝试卷曲。但我仍然想知道,浏览器如何准确地知道文件名?当我将此网址放入浏览器时,我会收到带有真实文件名的提示保存窗口。所以,当我之前使用: ini_set('user_agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.16) Gecko/2009121601 Ubuntu/9.04 (jaunty) Firefox/3.0.16' );我以为我就像一个浏览器:)
    • RFC 2183 描述了 Content-Disposition: 标头,并且它能够包含 filename 指令。浏览器解析这部分标头并从中获取各种元数据。检查我在我的答案中链接的答案,它描述了一种如何使用 PHP(和 cURL)检索此标头的方法。
    • 我测试了上面所有的例子。没有成功。我尝试了完整的示例类:stackoverflow.com/questions/6177661/…,但无法通过 cURL 获取原始文件名。即使文件名包含在 URL 中。有人可以根据任何公共文件(jpg或其他文件)放置工作示例。只需下载远程并以相同的名称保存在本地。我将不胜感激。谷歌搜索 2 天,没有任何想法:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 2022-08-13
    • 1970-01-01
    • 2015-10-06
    • 2016-03-10
    • 1970-01-01
    相关资源
    最近更新 更多