PHP REST API如何实现返回文件、触发浏览器或Postman自动下载
问题原因
当前代码仅构造了文件的访问URL,既没有发送触发下载所需的HTTP响应头,也没有输出文件实体内容,所以无法实现下载需求。同时原有SQL直接拼接参数的写法存在SQL注入风险,需要同步修正。
修正后的实现代码
public function downloadFile($param){ // 修正SQL注入风险,使用预处理参数绑定 $q = "SELECT * FROM data_file WHERE module_id = ?"; $stmt = $this->conn->prepare($q); $stmt->execute([$param]); $row = $stmt->fetch(PDO::FETCH_ASSOC); if (!$row || empty($row['file_name'])) { http_response_code(404); exit('文件记录不存在'); } $filename = $row['file_name']; // 拼接本地物理路径,__DIR__为当前脚本所在目录,可根据实际目录结构调整 $filePath = __DIR__ . '/../files/' . $filename; // 校验本地文件是否真实存在 if (!file_exists($filePath) || !is_file($filePath)) { http_response_code(404); exit('文件实体不存在'); } // 发送下载所需的HTTP响应头 header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . basename($filename) . '"'); header('Content-Length: ' . filesize($filePath)); // 清空之前可能存在的输出缓存,避免文件损坏 ob_clean(); flush(); // 直接输出文件内容,readfile内存占用更低,适合大文件下载 readfile($filePath); exit; }
关键注意事项
- 不要通过HTTP请求读取本地服务器上的文件,直接读取物理路径性能更高,也不会受
allow_url_fopen配置限制,之前使用cURL、file_get_contents请求URL失败大概率和配置或本地网络规则有关 - 输出文件前务必确保没有任何提前输出(包括PHP标签外的空格、换行、调试打印语句等),否则会导致下载的文件损坏无法打开
- 如果文件名包含中文,需要将
Content-Disposition中的文件名转为GBK编码,避免下载时文件名乱码 - 大文件下载建议使用分段读取输出的方式,避免一次性加载整个文件到内存导致服务超时或内存溢出
内容的提问来源于stack exchange,提问作者Vince
相关产品推荐
相关产品推荐

