PHP使用readfile下载PDF第一页空白报错但浏览器预览正常求助
问题修复方案
核心原因排查
- 多余输出破坏PDF文件结构:浏览器预览PDF时对格式容错率极高,但Adobe Acrobat对文件完整性校验严格,只要PHP在输出PDF内容前有1个字节的多余输出(比如PHP文件开头
<?php前的空格/换行、文件末尾?>后的空白字符、代码中意外的echo/var_dump输出、PHP报错提示),都会直接污染PDF的文件头,导致解析错误。 - Content-Length 与实际传输大小不匹配:如果你的站点开启了gzip压缩,web服务器会自动压缩PHP输出的内容,此时你手动设置的
Content-Length是原始文件的大小,和压缩后的实际传输大小不一致,会导致浏览器接收的文件被截断或多出冗余数据。 - 输出后未终止程序执行:
readfile执行完成后如果还有后续代码运行,可能产生额外输出追加到PDF文件末尾,同样会破坏文件结构。
修复后的代码示例
// 先清理所有之前的输出缓冲区,避免多余输出 ob_clean(); // 可选:如果开启了gzip,先关闭当前请求的压缩,保证Content-Length准确 // if (ob_get_level()) ob_end_clean(); header('Content-type: application/pdf'); header('Content-Disposition: attachment; filename="' . $docname . '.' . strtolower(end(explode('.', $doc['filename']))) . '"'); header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); header("Pragma: private"); header('Cache-Control: public, must-revalidate, max-age=0'); // 可选:如果关闭了gzip可以保留这行,否则建议删除让服务器自动计算传输大小 header("Content-Length: " . filesize('/filestore/' . $doc['filename'])); readfile('/filestore/' . $doc['filename']); // 强制终止程序,避免后续代码产生额外输出 exit;
额外排查点
- 检查处理下载逻辑的PHP文件是否删除了末尾的
?>标记,PHP文件末尾不需要加闭合标记,可彻底避免闭合标记后产生多余空白输出。 - 验证文件读取权限:确认PHP进程对
/filestore/目录下的文件有可读权限,避免读取失败输出错误信息到PDF内容中。 - 若有使用框架,检查是否有全局的响应后置处理逻辑自动追加内容到输出中,需在下载逻辑中跳过该类处理。
内容的提问来源于stack exchange,提问作者srt8driver
相关产品推荐
相关产品推荐

