php代码示例怎么实现文件下载_php文件下载代码示例【示例】
发布时间 - 2026-02-01 00:00:00 点击率:次下载需设 Content-Type: application/octet-stream 并配合 Content-Disposition: attachment;清空输出缓冲、检查文件可读、UTF-8 编码中文文件名;禁用 output_buffering,设置超时,校验路径防遍历。
header() 发送下载头时 Content-Type 必须设为 application/octet-stream
浏览器识别下载行为主要靠 Content-Type 和 Content-Disposition 两个响应头。如果 Content-Type 写成 text/plain 或留空,部分浏览器(尤其是 Chrome)会尝试内嵌显示,而不是弹出保存对话框。
实操建议:
-
Content-Type: application/octet-stream是最稳妥的选择,表示“未知二进制数据”,强制触发下载 - 避免使用
application/download或application/x-download—— 这些不是标准 MIME 类型,IE 以外基本不认 - 若需保留原始扩展名关联(如 .pdf 点开用 Acrobat 打开),
Content-Type可设为对应类型(如application/pdf),但必须配合Content-Disposition: attachment,否则仍可能被浏览器渲染
readfile() 前必须清空输出缓冲并禁止后续输出
PHP 脚本里任何额外空格、echo、warning、notice 都会导致 header 发送失败,报错 “Cannot modify header information – headers already sent”。常见于文件末尾多了一个换行,或 include 的配置文件里有 BOM 或空行。
实操建议:
- 开头加
ob_end_clean()或if (ob_get_level()) ob_end_flush();主动清理已有缓冲 - 下载逻辑后立即
exit;或die;,防止脚本继续执行输出无关内容 - 用
readfile($filepath)直接输出文件流,不要用file_get_contents()+echo,大文件会吃光内存 - 检查目标文件是否存在且可读:
if (!is_readable($filepath)) { http_response_code(404); exit; }
Content-Disposition 中的 filename 要做 UTF-8 兼容处理
中文文件名在 IE 和 Edge 上会乱码,在 Chrome/Firefox 上可能被截断或忽略。直接写 filename="报告.pdf" 不跨浏览器安全。
实操建议:
- 优先用
filename*=UTF-8''{encoded}格式(RFC 5987),例如:filename*=UTF-8''%E6%8A%A5%E5%91%8A.pdf - 同时提供 ASCII fallback:
filename="report.pdf",兼容老浏览器 - 用
rawurlencode()编码文件名(不是urlencode()),并替换空格为 %20(rawurlencode()已处理) - 完整头示例:
header('Content-Disposition: attachment; filename="report.pdf"; filename*=UTF-8\'\''.rawurlencode($zh_filename));
大文件下载要禁用 output_buffering 并设置 max_execution_time
默认 PHP 的 output_buffering 和 max_execution_time 会中断大文件传输。比如一个 500MB 的日志文件,边读边发时可能卡在 30 秒超时,或因缓冲区满导致内存溢出。
实操建议:
下载前加:
ini_set('output_buffering', 'Off'); ini_set('zlib.output_compression', 'Off');- 延长执行时间:
set_time_limit(0);(注意:CLI 模式下无效,Web 服务器如 Nginx 还有自身的 timeout 限制) - 对超大文件(>1GB),考虑用
fpassthru()替代readfile(),配合fopen()流式控制更稳 - Nginx 用户需同步检查
send_timeout和client_max_body_size配置,否则上传没问题、下载中途断连
realpath() + strpos() 检查是否在允许目录内,就直接拼接用户传入的 $_GET['file'],等于敞开目录遍历漏洞。
# php
# nginx
# 编码
# 浏览器
# app
# edge
# ai
# pdf
# stream
# 配置文件
# firefox
# chrome
# echo
# strpos
# if
# include
# fopen
# die
# bom
# ASCII
# 遍历
# 设为
# 大文件
# 清空
# 的是
# 尤其是
# 已有
# 执行时间
# 要做
# 扩展名
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Linux系统命令中screen命令详解
大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?
怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?
如何做网站制作流程,*游戏网站怎么搭建?
jQuery中的100个技巧汇总
如何安全更换建站之星模板并保留数据?
如何在阿里云购买域名并搭建网站?
实例解析angularjs的filter过滤器
如何快速生成可下载的建站源码工具?
iOS验证手机号的正则表达式
千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】
教你用AI将一段旋律扩展成一首完整的曲子
创业网站制作流程,创业网站可靠吗?
Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?
如何快速上传建站程序避免常见错误?
php结合redis实现高并发下的抢购、秒杀功能的实例
Laravel如何使用Livewire构建动态组件?(入门代码)
香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化
猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】
phpredis提高消息队列的实时性方法(推荐)
,南京靠谱的征婚网站?
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】
zabbix利用python脚本发送报警邮件的方法
SQL查询语句优化的实用方法总结
中山网站制作网页,中山新生登记系统登记流程?
Laravel如何编写单元测试和功能测试?(PHPUnit示例)
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
JS实现鼠标移上去显示图片或微信二维码
html5的keygen标签为什么废弃_替代方案说明【解答】
WordPress 子目录安装中正确处理脚本路径的完整指南
公司网站制作需要多少钱,找人做公司网站需要多少钱?
Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能
Firefox Developer Edition开发者版本入口
Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】
百度浏览器如何管理插件 百度浏览器插件管理方法
奇安信“盘古石”团队突破 iOS 26.1 提权
Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
如何用y主机助手快速搭建网站?
如何获取PHP WAP自助建站系统源码?
网站制作价目表怎么做,珍爱网婚介费用多少?
Laravel怎么判断请求类型_Laravel Request isMethod用法
Laravel如何配置Horizon来管理队列?(安装和使用)
详解Oracle修改字段类型方法总结
宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法
Laravel如何从数据库删除数据_Laravel destroy和delete方法区别
Laravel如何实现一对一模型关联?(Eloquent示例)
如何基于PHP生成高效IDC网络公司建站源码?


