PHP获取远程文件大小方法解析
时间:2026-04-01 16:08:29 320浏览 收藏
PHP中通过get_headers获取远程文件大小极不可靠,因其易受重定向、分块传输、动态脚本输出及CDN缓存干扰而导致Content-Length为空或错误;更稳健的方案是使用cURL手动控制HEAD请求——禁用自动跳转、设置超时、校验响应码,并优先从CURLINFO_CONTENT_LENGTH_DOWNLOAD提取尺寸;若失败,则退化为带Range: bytes=0-0的GET请求,解析Content-Range头获取总大小,同时结合Accept-Ranges支持判断与响应状态码(206优先采信,200需谨慎处理),最终实现对各类远程资源(静态文件、PHP下载脚本、CDN托管内容)的自适应、高兼容性大小探测。

get_headers 在 PHP 中确实能拿到 Content-Length,但**绝大多数情况下它不靠谱——尤其是对重定向、分块传输、动态脚本或 CDN 缓存后的响应**。
为什么 get_headers 返回的 Content-Length 经常是空或错的
HTTP 协议本身不要求服务器返回 Content-Length;现代服务更倾向用 Transfer-Encoding: chunked 或直接省略该头。PHP 的 get_headers 默认只发 HEAD 请求,而很多 Web 服务器(比如 Nginx + PHP-FPM)对 HEAD 的处理会丢掉 Content-Length,哪怕 GET 能拿到。
- 遇到 301/302 重定向时,
get_headers默认跟随,但中间跳转响应可能没Content-Length,最终返回的是最后一跳的头——而那一跳可能是空响应体或网关页 - PHP 脚本(如
download.php?id=123)通常用readfile()或fopen() + stream_copy_to_stream()输出,压根不设Content-Length头 - CDN 或反向代理(如 Cloudflare)可能剥离或伪造原始头,
Content-Length变成不可信值
真要获取远程文件大小,得换方法:用 curl 发 HEAD 并手动控制行为
比 get_headers 更可控,关键是显式关闭重定向、设置超时、检查真实响应码,并允许 fallback 到 GET(带 Range 头只取首字节)。
- 先用
curl_setopt($ch, CURLOPT_NOBODY, true)发HEAD,同时设CURLOPT_FOLLOWLOCATION为false - 检查
curl_getinfo($ch, CURLINFO_HTTP_CODE)是否为200;若为3xx,需手动解析Location头再试一次(不能依赖自动跳转) - 从
curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD)读大小——这个值是 cURL 内部解析响应头后提取的,比自己array_search更稳 - 如果该值为
-1或空,说明头里没给,可退化为GET+Range: bytes=0-0,然后看Content-Range头里的总长度(如bytes 0-0/1234567)
示例关键逻辑:
$ch = curl_init('https://example.com/file.zip');
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_exec($ch);
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
curl_close($ch);
别忽略 Content-Range 和 Accept-Ranges 这两个“备胎”头
有些服务(特别是静态文件托管或支持断点续传的 API)虽然不返回 Content-Length,但会返回 Accept-Ranges: bytes,配合一次带 Range: bytes=0-0 的 GET 请求,就能从 Content-Range 响应头里拿到完整尺寸。
Content-Range: bytes 0-0/8388608→ 总大小就是8388608- 若响应码是
206 Partial Content,说明服务支持分片,Content-Range可信;若是200,那这个Range请求被无视了,不能采信 - 注意:某些 CDN(如阿里云 OSS)对小文件会合并响应,
Range请求可能直接返回完整内容且状态码为200,此时需靠Content-Length或Content-Range是否存在来判断
真正难的不是写几行代码,而是得根据目标 URL 的实际响应特征动态选策略:先 HEAD,失败就 Range,再失败才考虑下载整个头(不推荐)。没人能保证一个函数调用就搞定所有远程地址。
理论要掌握,实操不能落!以上关于《PHP获取远程文件大小方法解析》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!
相关阅读
更多>
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
最新阅读
更多>
-
439 收藏
-
236 收藏
-
236 收藏
-
413 收藏
-
273 收藏
-
362 收藏
-
386 收藏
-
249 收藏
-
419 收藏
-
279 收藏
-
275 收藏
-
193 收藏
课程推荐
更多>
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习