在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?

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?