在PHP中强制下载图像。 在本地工作但在实时Linux服务器上中断

问题描述:

I am forcing the download of an image through my website.

Forced download works fine on Apache/Windows development machine.

However it pushes junk characters to the screen when live on my linux web server.

e.g. �����JFIF��H�H����6Exif��MM�*����
  • Firefox - junk
  • Chrome - junk
  • Internet Explorer 7 - displays the image in the page

    $fileName = basename($filePath);
    $fileSize = filesize($filePath);
    
    
    // Output headers.
    header("Cache-Control: private");
    header("Content-Type: Image/jpeg");
    header("Content-Length: ".$fileSize);
    header("Content-Disposition: attachment; filename=".$fileName);
    
    
    // Output file.
    readfile ($filePath);                   
    exit();
    

What differences might there be on my live server that would cause it to break?

我正在通过我的网站强制下载图像。 p>

Forced 下载在Apache / Windows开发机器上工作正常。 p>

然而,当它在我的linux网络服务器上运行时,它会将垃圾字符推送到屏幕上。 p>

 如  �����JFIF��H�H����6Exif��MM�*����
  code>  pre> 
 
 
  • Firefox - 垃圾 li>
  • Chrome - 垃圾 li>
  • Internet Explorer 7 - 在页面中显示图像 p>

      $ fileName  = basename($ filePath); 
     $ fileSize = filesize($ filePath); 
     
     
     //输出标题。
    header(“Cache-Control:private”); 
    header(“Content-Type:Image  / jpeg“); 
    header(”Content-Length:“。$ fileSize); 
    header(”Content-Disposition:attachment; filename =“。$ fileName); 
     
     
     //输出文件。
    readfile  ($文件路径);  
    exit(); 
      code>  pre>  li> 
      ul> 
     
     

    我的实时服务器可能存在哪些差异会导致其中断 ? strong> p> div>

Hat tip (and +1) to stillstanding, who pointed out using fifo, but I thought I'd provide an example here to help. This example requires the fifo extension installed, and has been hacked out and slightly modified from some other code of mine.

    $filename = 'blarg.jpg';
    $filepath = '/foo/bar/blarg.jpg';
    $finfo    = new finfo(FILEINFO_MIME);
    $mime     = $finfo->file($file);

    // Provide a default type in case all else fails
    $mime = ($mime) ? $mime : 'application/octet-stream';

    header('Pragma: public');
    header('Content-Transfer-Encoding: binary');
    header('Content-type: ' . $mime);
    header('Content-Length: ' . filesize($filepath));
    header('Content-Disposition: attachment; filename="' . $filename . '"');

    header('Content-transfer-encoding: 8bit');
    header('Expires: 0');
    header('Pragma: cache');
    header('Cache-Control: private');

You have an incorrect MIME type in the header. Use finfo so you can send the correct one instead of transmitting everything as an application/stream, otherwise browser behavior will be unpredictable.

Shouldn't the Content-Type be set to image?