Question

I have a script that allows users to 'save as' a pdf, this is the script -

<?php
header("Content-Type: application/octet-stream");

$file = $_GET["file"] .".pdf";
header("Content-Disposition: attachment; filename=" . urlencode($file));   
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");            
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp))
{
    echo fread($fp, 65536);
    flush(); // this is essential for large downloads
} 
fclose($fp);
?>

An error log is being created and gets to be more than a gig in a few days the errors I receive are-

[10-May-2010 12:38:50] PHP Warning:  filesize() [<a href='function.filesize'>function.filesize</a>]: stat failed for BYJ-Timetable.pdf in /home/byj/public_html/pdf_server.php on line 10
[10-May-2010 12:38:50] PHP Warning:  Cannot modify header information - headers already sent by (output started at /home/byj/public_html/pdf_server.php:10) in /home/byj/public_html/pdf_server.php on line 10
[10-May-2010 12:38:50] PHP Warning:  fopen(BYJ-Timetable.pdf) [<a href='function.fopen'>function.fopen</a>]: failed to open stream: No such file or directory in /home/byj/public_html/pdf_server.php on line 12
[10-May-2010 12:38:50] PHP Warning:  feof(): supplied argument is not a valid stream resource in /home/byj/public_html/pdf_server.php on line 13
[10-May-2010 12:38:50] PHP Warning:  fread(): supplied argument is not a valid stream resource in /home/byj/public_html/pdf_server.php on line 15
[10-May-2010 12:38:50] PHP Warning:  feof(): supplied argument is not a valid stream resource in /home/byj/public_html/pdf_server.php on line 13
[10-May-2010 12:38:50] PHP Warning:  fread(): supplied argument is not a valid stream resource in /home/byj/public_html/pdf_server.php on line 15

The line 13 and 15 just continue on and on... I'm a bit of a newbie with php so any help is great. Thanks guys Nik

Was it helpful?

Solution

What's happening is:

  • Your file could not be found, so the filesize function errorred out
  • Because it errored out, it produced output.
  • Once you have output, you CANNOT send anymore headers
  • Because you are sending more headers, you are getting more errors

Because your file was not found, your while loop will error out forever, because you are trying to read from a file that does not exist.

ALSO: A file has ONE content-type, not 4. You need to pick one of the content-types and use that one, you can't pass them all.

And finally: Your script is horribly insecure. If someone passed ?file=/home/apache/secret_db_passwords.txt then they would immediately have access to your stuff.

Edit: PHP has a function called readfile that is designed to handle exactly what you are trying to do. You do not need to have a while loop run thru the file sending bit by bit. Just do readfile($file); and the web server will handle all that crap for you

OTHER TIPS

Couple of things:

  1. You can only set a header once, as far as I know, so setting your Content-Type four times is pointless.

  2. It might help if you set the content type to a pdf mime type, in this case I'd go with application/pdf.

  3. Force Download is not a content type, as far as I know. The browser will download if you set the Content-Disposition to attachment, which you already have.

  4. Finally, if there is no PDF version of the file (which it looks like there isn't) why are you trying to stream from it? You probably want to set your $file variable to the actual file, and make another variable like $filename for setting the PDF file name that is output to the user.

[10-May-2010 12:38:50] PHP Warning:  fopen(BYJ-Timetable.pdf) [<a href='function.fopen'>function.fopen</a>]: failed to open stream: No such file or directory in /home/byj/public_html/pdf_server.php on line 12

This should tell you what you need to know: fopen and filesize both need to be passed the name, and path to, the file to be opened. In this case, you're just passing the filename, no path, so it's trying to find it in the current directory the script is running in. In this case, /home.byj/public_html/

To fix this, you need to apply a relative or absolute path to the PDF file to open to these functions, not just the name of the PDF file itself.

Instead of looping and reading pieces of the file can you use: http://php.net/manual/en/function.readfile.php?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top