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-TypeContent-Disposition 两个响应头。如果 Content-Type 写成 text/plain 或留空,部分浏览器(尤其是 Chrome)会尝试内嵌显示,而不是弹出保存对话框。

实操建议:

  • Content-Type: application/octet-stream 是最稳妥的选择,表示“未知二进制数据”,强制触发下载
  • 避免使用 application/downloadapplication/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_bufferingmax_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_timeoutclient_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


相关推荐: Laravel如何编写单元测试和功能测试?(PHPUnit示例)  三星、SK海力士获美批准:可向中国出口芯片制造设备  如何快速搭建支持数据库操作的智能建站平台?  敲碗10年!Mac系列传将迎来「触控与联网」双革新  网站制作价目表怎么做,珍爱网婚介费用多少?  网页制作模板网站推荐,网页设计海报之类的素材哪里好?  SQL查询语句优化的实用方法总结  Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析  Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程  专业商城网站制作公司有哪些,pi商城官网是哪个?  php json中文编码为null的解决办法  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  长沙企业网站制作哪家好,长沙水业集团官方网站?  简历在线制作网站免费版,如何创建个人简历?  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  如何在IIS中新建站点并解决端口绑定冲突?  Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】  高性能网站服务器配置指南:安全稳定与高效建站核心方案  如何在阿里云域名上完成建站全流程?  Laravel怎么写单元测试_PHPUnit在Laravel项目中的基础测试入门  使用spring连接及操作mongodb3.0实例  黑客如何通过漏洞一步步攻陷网站服务器?  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  如何挑选优质建站一级代理提升网站排名?  CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】  宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程  Laravel怎么生成URL_Laravel路由命名与URL生成函数详解  弹幕视频网站制作教程下载,弹幕视频网站是什么意思?  谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  Swift中循环语句中的转移语句 break 和 continue  PHP 实现电台节目表的智能时间匹配与今日/明日轮播逻辑  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  免费视频制作网站,更新又快又好的免费电影网站?  java ZXing生成二维码及条码实例分享  个人摄影网站制作流程,摄影爱好者都去什么网站?  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  在Oracle关闭情况下如何修改spfile的参数  如何有效防御Web建站篡改攻击?  javascript中对象的定义、使用以及对象和原型链操作小结  HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】  安克发布新款氮化镓充电宝:体积缩小 30%,支持 200W 输出  网站页面设计需要考虑到这些问题  厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?  JavaScript如何操作视频_媒体API怎么控制播放  iOS正则表达式验证手机号、邮箱、身份证号等  如何用搬瓦工VPS快速搭建个人网站?  laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法  如何为不同团队 ID 动态生成多个非值班状态按钮  Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲