title: PHP: read and present a PDF file to download via PHP is generating corrupted files in some cases
body: <p>I am using the following to read and present a PDF file to the user:</p>
  
  <pre><code>$file='file.pdf';
  $filepath="/path-to-download-folder/$file";
  if(!is_file($filepath)) die('Ops!');
  $f=fopen($filepath,'r');
  if($f){
      header('Cache-Control: no-store, no-cache, must-revalidate');
      header('Content-Type: '.mime_content_type($filepath));
      header('Content-Length: '.filesize($filepath));
      header('Content-Disposition: attachment; filename="'.$file.'"');
      fpassthru($f);
  }else die("Ops!");
  fclose($f);
  </code></pre>
  
  <p>However some folks are reporting that the PDF file is corrupted when they try to open it.</p>
  
  <p>Am I doing something wrong or forgetting some important header? Is there a better way to achieve the same?</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>I sent the PDF file via email and the users got to open the file. So it must be something with the way PHP and Nginx are serving the file.</p>
  
  <p>So I turned off gzip on Nginx but the error continues.</p>
  
  <p>I also applied the tips bellow so the code is now like this:</p>
  
  <pre><code>$file='file.pdf';
  $filepath="/path-to-download-folder/$file";
  
  if(!file_exists($filepath)){
    header('HTTP/1.1 404 Not Found');
    exit;
  }elseif(!is_file($filepath) or !is_readable($filepath)){
    header('HTTP/1.1 403 Forbidden');
    exit;
  }else{
      header('Cache-Control: no-store, no-cache, must-revalidate');
      header('Content-Type: '.mime_content_type($filepath));
      header('Content-Length: '.filesize($filepath));
      header('Content-Disposition: attachment; filename="'.$file.'"');
  
      set_time_limit(0); // Big files/slow connections may result in incomplete downloads
      readfile($filepath);
      die;
  }
  </code></pre>
  
  <p>However I still am receiving this error: <a href="http://mlkshk.com/r/8FGS" rel="nofollow">http://mlkshk.com/r/8FGS</a></p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>I made a diff among the files:</p>
  
  <pre><code>compare -verbose -debug coder Dicas1.pdf Dicas1A.pdf -compose src OUT.tmp
  </code></pre>
  
  <p>With this output:</p>
  
  <pre><code>"gs" -q -dQUIET -dPARANOIDSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 "-sDEVICE=pnmraw" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r72x72"  "-sOutputFile=/tmp/magick-XXuCqreY" "-f/tmp/magick-XXNkQbcr" "-f/tmp/magick-XXoICX9T"
     **** Warning: File has some garbage before %PDF- .
     **** Error: Cannot find a %%EOF marker anywhere in the file.
     **** Warning:  An error occurred while reading an XREF table.
     **** The file has been damaged.  This may have been caused
     **** by a problem while converting or transfering the file.
     **** Ghostscript will attempt to recover the data.
  </code></pre>
  
  <p>So I opened it in Leafpad:</p>
  
  <p>Original file:</p>
  
  <pre><code>%PDF-1.5
  %Çì¢
  1 0 obj
  &lt;&lt;
  /Type /Catalog
  /Outlines 3 0 R
  /Pages 4 0 R
  /Dests 5 0 R
  /AcroForm 6 0 R
  /Names 7 0 R
  /Threads 8 0 R
  /PageLayout /SinglePage
  /ViewerPreferences
  &lt;&lt;
  /PageDirection /L2R
   &gt;&gt;
  &gt;&gt;
  endobj
  2 0 obj
  &lt;&lt;
  /Creator (Scribus 1.5.0.svn)
  /Producer (Scribus PDF Library 1.5.0.svn)
  /Title &lt;&gt;
  /Author &lt;&gt;
  /Subject &lt;&gt;
  /Keywords &lt;&gt;
  /CreationDate (D:20111016162546Z)
  /ModDate (D:20111016162546Z)
  /Trapped /False
  &gt;&gt;
  endobj
  9 0 obj
  &lt;&lt;
  /Length 154566
  /Length1 275572
  /Filter /FlateDecode
  &gt;&gt;
  stream
  </code></pre>
  
  <p>File served by PHP and Nginx:</p>
  
  <pre><code>6Wm931Ja.G46X5WID+1K9G93F.3FD.2IXCWm&lt;br&gt;%PDF-1.5
  %Çì¢
  1 0 obj
  &lt;&lt;
  /Type /Catalog
  /Outlines 3 0 R
  /Pages 4 0 R
  /Dests 5 0 R
  /AcroForm 6 0 R
  /Names 7 0 R
  /Threads 8 0 R
  /PageLayout /SinglePage
  /ViewerPreferences
  &lt;&lt;
  /PageDirection /L2R
   &gt;&gt;
  &gt;&gt;
  endobj
  2 0 obj
  &lt;&lt;
  /Creator (Scribus 1.5.0.svn)
  /Producer (Scribus PDF Library 1.5.0.svn)
  /Title &lt;&gt;
  /Author &lt;&gt;
  /Subject &lt;&gt;
  /Keywords &lt;&gt;
  /CreationDate (D:20111016162546Z)
  /ModDate (D:20111016162546Z)
  /Trapped /False
  &gt;&gt;
  endobj
  9 0 obj
  &lt;&lt;
  /Length 154566
  /Length1 275572
  /Filter /FlateDecode
  &gt;&gt;
  stream
  </code></pre>
  
  <p>So this is the garbage PHP is puting in the begining of the file:</p>
  
  <p><code>6Wm931Ja.G46X5WID+1K9G93F.3FD.2IXCWm&lt;br&gt;</code></p>
  
  <p>And I found that a session value was being echoed in another part of the code and that was the real problem since the beginning.</p>
  
  <p>Thanks.</p>