PHP使用readfile强制下载失效问题求助
PHP强制下载PDF文件失效问题排查与修复
问题核心原因
你的代码存在两个关键错误,导致下载功能失效并触发“文件不存在”提示:
- 路径引用错误:
readfile($fileName)使用的是文件名而非完整路径$filePath,PHP无法定位到pdf目录下的文件,直接进入else分支。 - 相对路径不确定性:
./pdf/是基于当前脚本的相对路径,若脚本所在目录与pdf目录层级不符,会导致路径解析错误。
修复后的代码
<?php // 提前开启输出缓冲,避免前置输出破坏header ob_start(); if(!empty($_GET['docsbelong'])){ // 过滤文件名,防范目录遍历攻击 $fileName = basename($_GET['docsbelong']); // 使用绝对路径(__DIR__表示当前脚本所在目录的绝对路径) $filePath = __DIR__ . '/pdf/' . $fileName; // 同时检查文件存在性与可读性 if(!empty($fileName) && file_exists($filePath) && is_readable($filePath)){ // 清空缓冲,确保header能正常发送 ob_clean(); ob_end_flush(); // 设置响应头 header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0"); header("Content-Description: File Transfer"); header("Content-Disposition: attachment; filename=\"$fileName\""); header("Content-Type: application/pdf"); header("Content-Transfer-Encoding: binary"); // 添加文件大小头,帮助浏览器显示下载进度 header("Content-Length: " . filesize($filePath)); // 使用完整路径读取文件 readfile($filePath); exit; }else{ echo 'El archivo no existe.'; } } ?>
关键修改说明
- 修正readfile路径:将
readfile($fileName)改为readfile($filePath),确保PHP能正确找到目标文件。 - 改用绝对路径:通过
__DIR__拼接绝对路径,避免相对路径因脚本位置变化导致的解析错误。 - 输出缓冲控制:
ob_start()、ob_clean()、ob_end_flush()确保发送header前无任何输出(包括空白字符、BOM头),避免header失效。 - 增加可读性检查:
is_readable($filePath)验证Web服务器进程是否有权限读取文件,避免因权限问题导致的下载失败。 - 补充Content-Length头:让浏览器获取文件大小,显示准确的下载进度。
内容的提问来源于stack exchange,提问作者Amanda Muñoz
相关产品推荐
相关产品推荐

