【问题标题】:PHP force download corrupt PDF filePHP强制下载损坏的PDF文件
【发布时间】:2016-07-07 08:54:07
【问题描述】:

我浏览了有关 Stack Overflow 的所有文章,但无法解决我的问题。我正在使用以下代码:

$file = $_GET['url'];
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"'); 
header('Content-Length: ' . filesize($file));
readfile($file);
exit;

上面提到的代码是从根目录正上方下载文件,是的,它正在下载 PDF 文件,但文件只有 1KB 大小,而不是原始大小。 $_GET['url'] 在其中接收../dir/dir/filename.pdf。文件名也是其中的空格。出于安全原因,我不能共享文件名。

请让我知道我哪里出错了。

【问题讨论】:

  • 为了进一步扩展,我还用 application/pdf 替换了 application/octet-stream。
  • 问题是“PHP(如何)强制下载损坏的 PDF 文件”,但在你的问题中你说:“上面提到的代码正在下载文件” - 那么问题是什么?跨度>
  • 上面的代码正在下载一个损坏的文件。当我检查 PDF 文件的大小时,它是 1KB。抱歉标题令人困惑。
  • 在第一行之后,添加这段代码并重试echo '<pre>IS FILE: ' . (is_file($file) ? 'YES!' : 'NO :(') . '</pre>'; - 你看到了什么?
  • 这是你的问题 - 你必须提供一个有效的文件名。

标签: php file pdf


【解决方案1】:

请确保您使用 Web 服务器路径来访问该文件 - 例如,您的路径可能是:/home/yourusername/public/sitename/downloads/<filename>,您应该先检查 - 以帮助您在 PHP 脚本的顶部运行它以找出当前脚本的完整路径:

echo '<pre>FILE PATH: '.print_r(__FILE__, true).'</pre>';
die();

仅使用urlencode() 发送带有URL 的文件名,并在接收PHP 脚本上使用urldecode() 来处理任何字符编码问题。

请看这里:http://php.net/manual/en/function.urlencode.php 在这里:http://php.net/manual/en/function.urldecode.php

所以你在哪里创建你的网址:

&lt;a href="/my-download-url/&lt;?= urlencode('file name.pdf') ?&gt;"&gt;Download File&lt;/a&gt;

在你的 php 脚本中:

$file_base_path = '/home/yourusername/public/sitename/downloads/';
$file = urldecode($_GET['url']);
$file = $file_base_path . $file;
$file = $_GET['url'];
if (file_exists($file))
{
    if (FALSE!== ($handler = fopen($file, 'r')))
    {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: chunked'); //changed to chunked
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        //header('Content-Length: ' . filesize($file)); //Remove

        //Send the content in chunks
        while(false !== ($chunk = fread($handler,4096)))
        {
            echo $chunk;
        }
    }
    exit;
}
echo "<h1>Content error</h1><p>The file does not exist!</p>";

希望对你有帮助!

【讨论】:

  • 它只是失败的文件存在......甚至没有输入if。我的路径/网址应该是什么?它应该是http的全部吗?还是使用“../dir/dir/filename.pdf”就足够了?
  • 你需要找出文件所在的位置,否则你将一事无成。是的,您可以使用相对路径,但参考正在执行的脚本的位置必须是正确的。最好找出完整路径并使用我上面的代码填充$file_base_path
  • woohoo... 好的,所以它现在正在下载正确的文件,但唯一的问题是它不是带有 .pdf 扩展名的下载。我可以用 openwith 打开下载的文件... file_base_path 技巧奏效了。我怎样才能让它下载扩展名为 .pdf 的文件?将 Content-Type 更改为 application/pdf?同样在您上面第 4 行的代码中,我认为我们不需要该行。
  • @SyedMHammadKazmi - 太棒了!尝试使用:Content-Disposition = 'attachment; filename='.basename($file).'.pdf'
  • @SyedMHammadKazmi - 如果这解决了您的问题,请将我的答案标记为已接受的答案并投票。谢谢!
猜你喜欢
  • 2013-03-31
  • 1970-01-01
  • 2012-12-05
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 2019-08-19
相关资源
最近更新 更多