1

我有一个脚本,允许用户“另存为”pdf,这是脚本 -

<?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 的新手,所以任何帮助都很棒。谢谢大家尼克

4

4 回答 4

4

正在发生的事情是:

  • 找不到您的文件,因此filesize函数出错了
  • 因为它出错了,所以它产生了输出。
  • 一旦你有输出,你不能再发送标题
  • 因为您要发送更多标头,所以您会收到更多错误

因为找不到您的文件,所以您的 while 循环将永远出错,因为您正在尝试从不存在的文件中读取。

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

最后:您的脚本非常不安全。如果有人通过?file=/home/apache/secret_db_passwords.txt,那么他们将立即可以访问您的东西。

编辑:PHP 有一个名为的函数readfile,旨在准确处理您正在尝试执行的操作。您不需要通过文件一点一点地运行 while 循环。只需这样做readfile($file);,Web 服务器将为您处理所有这些废话

于 2010-05-11T03:31:57.110 回答
1

几件事:

  1. 据我所知,您只能设置一次标题,因此设置Content-Type四次是没有意义的。

  2. 如果将内容类型设置为 pdf mime 类型可能会有所帮助,在这种情况下我会选择application/pdf.

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

  4. 最后,如果没有文件的 PDF 版本(看起来没有),你为什么要尝试从中流式传输?您可能希望将$file变量设置为实际文件,并创建另一个变量,例如$filename设置输出给用户的 PDF 文件名。

于 2010-05-11T03:33:26.480 回答
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

这应该告诉您您需要知道的内容:fopen两者filesize都需要传递要打开的文件的名称和路径。在这种情况下,您只是传递文件名,没有路径,因此它试图在脚本运行的当前目录中找到它。在这种情况下,/home.byj/public_html/

要解决此问题,您需要对 PDF 文件应用相对或绝对路径以打开这些功能,而不仅仅是 PDF 文件本身的名称。

于 2010-05-11T03:34:08.430 回答
1

您可以使用http://php.net/manual/en/function.readfile.php代替循环和读取文件片段吗?

于 2010-05-11T03:36:38.723 回答