【问题标题】:Using the default filename (content_disposition) when downloading with CURL使用 CURL 下载时使用默认文件名 (content_disposition)
【发布时间】:2011-01-05 13:41:27
【问题描述】:

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

Content-Disposition:附件;文件名=foo.png

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

【问题讨论】:

    标签: php curl


    【解决方案1】:

    这是一个没有 curl 的解决方案,但必须为此启用 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);
    

    更新: Content-Disposition 中的文件名可以包含空格(在这种情况下,它们用单引号或双引号编写)。我用第二个 preg_match 块解决了这个问题。

    【讨论】:

      【解决方案2】:
      <?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

      【讨论】:

        【解决方案3】:

        发出 HEAD 请求,匹配文件名(使用正则表达式),然后下载文件。

        【讨论】:

        • 发出两个请求是浪费。而且不能保证目标确实支持 HEAD。
        猜你喜欢
        • 1970-01-01
        • 2012-09-03
        • 1970-01-01
        • 2021-10-21
        • 2014-04-06
        • 2016-05-02
        • 1970-01-01
        • 2016-04-13
        • 2019-10-02
        相关资源
        最近更新 更多