使用CURL下载时使用默认文件名(content_disposition)

时间:2010-01-15 15:24:49

标签: php curl

我正在尝试使用PHP&amp ;;下载一些文件CURL,但我没有看到使用默认建议文件名的简单方法(在HTTP响应头中为

内容 - 处置:附件;文件名= foo.png

)。有没有更简单的方法来获取完整的标题,解析文件名并重命名?

3 个答案:

答案 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请求,匹配文件名(使用正则表达式),然后下载文件。