PHP强制浏览器下载文件(两种方式)

时间:2013-08-02 23:26:03

标签: php file download

我想要一个php脚本来下载任何类型的文件而无需打开它。我发现了以下功能,在我看来有点不同,但我不知道哪个更好。请让我知道哪一个更好,更可靠:

  1. 来自PHP Manual

    $file = 'monkey.gif';
    
    if (file_exists($file)) {
      header('Content-Description: File Transfer');
      header('Content-Type: application/octet-stream');
      header('Content-Disposition: attachment; filename='.basename($file));
      header('Content-Transfer-Encoding: binary');
      header('Expires: 0');
      header('Cache-Control: must-revalidate');
      header('Pragma: public');
      header('Content-Length: ' . filesize($file));
      ob_clean();
      flush();
      readfile($file);
      exit;
    }
    
  2. 来自其他教程:

    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header("Content-Disposition: attachment; filename=\"{$file->filename}\"");
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: " . $filesize);
    
    // download
    // @readfile($file_path);
    $dwn_file = @fopen($file_path,"rb");
    if ($dwn_file) {
      while(!feof($dwn_file)) {
        print(fread($dwn_file, 1024*8));
        flush();
        if (connection_status()!=0) {
          @fclose($dwn_file);
          die();
        }
      }
      @fclose($dwn_file);
    }
    

3 个答案:

答案 0 :(得分:5)

当您查看正在发送的标头时,两者实际上非常相似,这是强制下载的原因。不同之处在于文件的读取方式。第一个使用readfile()作为抽象,而第二个使用每字节读取字节。

第二个示例也多次使用@符号suppress errors,这可能不是一件好事。

我会使用PHP手册中的代码。它更简单,更不容易出错,而且更具可读性。

答案 1 :(得分:1)

它们基本相同。你想要的是标题

header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=\"{$file->filename}\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $filesize);
header('Content-Type: image/gif');

然后只输出文件。这可以通过多种方式完成,但我建议简单地说:

readfile($filename);

因为它不言自明。它将读取文件并将其输出到输出缓冲区(即浏览器)。

但请注意,如果您正在输出内容,则应将Content-Type标头设置为image / gif。

答案 2 :(得分:0)

这是一个意见,但我会使用第一个,它更快更清洁。