PHP create huge errors file on my server feof() fread()
I have a script that allows users开发者_StackOverflow社区 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
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
Couple of things:
You can only set a header once, as far as I know, so setting your
Content-Type
four times is pointless.It might help if you set the content type to a pdf mime type, in this case I'd go with
application/pdf
.Force Download
is not a content type, as far as I know. The browser will download if you set theContent-Disposition
toattachment
, which you already have.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?
精彩评论