2010-05-11 85 views
1

我有一个脚本,允许用户“另存为”一个PDF格式,这是脚本 -PHP创造巨大的错误,在我的服务器FEOF文件()FREAD()

<?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); 
?> 

正在创建错误日志并获得比演出更在几天我收到的错误是 -

[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 

线13和15只是继续和...我有点用PHP新手,所以任何帮助是伟大的。 谢谢你们 聂

+0

如何对某些格式进行编码,该代码难以读取 – 2010-05-11 03:26:16

回答

4

发生了什么事是:

  • 您的文件找不到,所以filesize功能errorred出
  • 因为它出错了,它产生的输出。
  • 一旦你有输出,你不能再
  • 因为你发送更多的报头,你得到更多的错误

因为你找不到文件发送标题,while循环就会报错了永远的,因为您正尝试从不存在的文件读取数据。

ALSO:文件有一个内容类型,而不是4.您需要选择其中一种内容类型并使用该内容类型,但不能全部传递它们。

最后:你的剧本是可怕的不安全。如果有人通过?file=/home/apache/secret_db_passwords.txt,那么他们会立即访问你的东西。

编辑:PHP有一个名为readfile功能是专门用来处理正是你正在尝试做的。您不需要通过一点一点地发送文件来运行while循环。只是做readfile($file);和Web服务器将处理所有的垃圾为你

+0

+1为安全捕获! – Anthony 2010-05-11 03:33:55

+0

太棒了...但现在我有点担心,因为我已经在众多网站上使用这个脚本,这些网站上有敏感信息......哦,亲爱的!我明白你在说什么,我只是不确定如何实施修复程序?我剪切和粘贴该脚本,因为这是我所有的技能允许当涉及到PHP = \ – Nik 2010-05-11 04:12:11

+0

那么你应该设置文件名是类似的东西(像所有的字母/数字)。这样你可以去除所有其他角色。你也可以试着去掉所有'/'的东西,但我不确定是否有一个简单的'插件'破解来解决这个问题。但作为一个经验法则,你绝不应该让用户指定直接插入到表中的参数,或者用于访问文件(没有正确清理它们) – 2010-05-11 04:14:16

1

几件事情:

  1. 只能设置一个标题一次,因为据我所知,所以设置你的Content-Type四次无意义。

  2. 如果内容类型设置为PDF MIME类型,在这种情况下,我与application/pdf走这可能会有帮助。

  3. Force Download不是内容类型,据我所知。如果您将Content-Disposition设置为attachment,则浏览器将下载。

  4. 最后,如果有文件(这看起来没有)没有PDF版本,为什么你想从中流?你可能想你$file变量设置为实际的文件,并让另一个变量一样$filename用于设置输出到用户的PDF文件名。

+0

从技术上讲,您可以发送多个相同的标题。然而,你必须做'header(“Header”,false)'false'告诉它追加。 (但是,它从来没有用于Content-Type标头,因为这没有意义) – 2010-05-11 03:36:38

+0

我半虚张声势,但我很高兴在这种情况下我是对的。感谢您的高举。 – Anthony 2010-05-11 03:51:32

1
[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 

这应该告诉你,你需要知道:fopenfilesize都需要传递的名称,并且,该文件被打开路径。在这种情况下,您只是传递文件名,没有路径,所以它试图在脚本运行的当前目录中找到它。在这种情况下,要解决此问题,您需要应用一个相对或PDF文件的绝对路径来打开这些功能,而不仅仅是PDF文件本身的名称。