我正在尝试使用PHP&amp ;;下载一些文件CURL,但我没有看到使用默认建议文件名的简单方法(在HTTP响应头中为
内容 - 处置:附件;文件名= foo.png
)。有没有更简单的方法来获取完整的标题,解析文件名并重命名?
答案 0 :(得分:11)
<?php
$targetPath = '/tmp/';
$filename = $targetPath . 'tmpfile';
$headerBuff = fopen('/tmp/headers', 'w+');
$fileTarget = fopen($filename, 'w');
$ch = curl_init('http://www.example.com/');
curl_setopt($ch, CURLOPT_WRITEHEADER, $headerBuff);
curl_setopt($ch, CURLOPT_FILE, $fileTarget);
curl_exec($ch);
if(!curl_errno($ch)) {
rewind($headerBuff);
$headers = stream_get_contents($headerBuff);
if(preg_match('/Content-Disposition: .*filename=([^ ]+)/', $headers, $matches)) {
rename($filename, $targetPath . $matches[1]);
}
}
curl_close($ch);
我最初尝试使用php://memory而不是/tmp/headers
,因为使用临时文件这类事情是草率的,但由于某种原因我无法正常工作。但至少你明白了......
或者,您可以使用CURLOPT_HEADERFUNCTION
答案 1 :(得分:4)
这是一个没有卷曲的解决方案,但必须为此启用url_fopen。
$response_headers = get_headers($url,1);
// first take filename from url
$filename = basename($url);
// if Content-Disposition is present and file name is found use this
if(isset($response_headers["Content-Disposition"]))
{
// this catches filenames between Quotes
if(preg_match('/.*filename=[\'\"]([^\'\"]+)/', $response_headers["Content-Disposition"], $matches))
{ $filename = $matches[1]; }
// if filename is not quoted, we take all until the next space
else if(preg_match("/.*filename=([^ ]+)/", $response_headers["Content-Disposition"], $matches))
{ $filename = $matches[1]; }
}
// if no Content-Disposition is found use the filename from url
// before using the filename remove all unwanted chars wich are not on a-z e.g. (I the most chars which can be used in filenames, if you like to renove more signs remove them from the 1. parameter in preg_replace
$filename = preg_replace("/[^a-zA-Z0-9_#\(\)\[\]\.+-=]/", "",$filename);
// at last download / copy the content
copy($url, $filename);
UPDATE: Content-Disposition中的文件名可以包含空格(在这种情况下,它们用单引号或双引号书写)。我用第二个preg_match块解决了这种情况。
答案 2 :(得分:0)
发出HEAD请求,匹配文件名(使用正则表达式),然后下载文件。