PHP文件不能真正变成MP4,所谓“转换”实为误命名或动态输出MP4流;验证关键看HTTP响应状态码200、Content-Type为video/mp4且无HTML/JSON混杂,以及前12字节是否为MP4标准ftyp box(00 00 00 18 66 74 79 70)。
PHP 文件本身不能“变成” MP4 格式,它只是服务器端脚本,而 MP4 是二进制媒体容器格式。所谓“PHP 文件变 MP4”,实际场景通常只有两种可能:一是误传了 PHP 文件却命名为 .mp4(比如把 video.php 改名成 video.mp4),二是后端用 PHP 动态生成或代理 MP4 流(如通过 readfile() 或 fpassthru() 输出真实 MP4 数据)。验证是否“转成功”,本质是验证响应内容是否为合法 MP4 字节流,而非 PHP 错误页或 HTML。
关键看 HTTP 响应头和原始字节,而不是文件扩展名或浏览器能否“播放”。常见错误是只检查 Content-Type: video/mp4,但这个头可以被 PHP 随意伪造,毫无校验价值。
curl -I 检查状态码必须是 200(不是 500 或 302),且 Content
-Type 仅为 video/mp4(不含 text/html 或 application/json)curl -s http://yoursite.com/video.php | head -c 12 | hexdump -C 查看前 12 字节:真实 MP4 文件开头通常是 00 00 00 18 66 74 79 70(即 ftyp box),若看到 3C 3F 70 68 70()或 3C 21 44 4F 43()说明输出的是 PHP/HTML 源码
file video.bin 命令识别类型(Linux/macOS),输出含 MPEG v4 system layer 或 ISO Media 才可信即使 PHP 脚本逻辑正确,也常因环境配置导致输出损坏。MP4 对字节完整性极其敏感,任何额外空格、BOM、错误警告都会让播放器直接失败。
hexdump -C script.php | head 检查开头是否为 ef bb bf
echo、var_dump、未捕获的 Notice/Warning;可在脚本开头加 error_reporting(0); ini_set('display_errors', '0');
header('Content-Type: video/mp4'); 且不能有任何输出在它之前(包括空白行)ob_end_clean(); 清除可能存在的输出缓冲,再用 readfile($real_mp4_path); 或 fpassthru($fp); 直接输出二进制流仅靠 HTTP 头和文件头还不够——有些 PHP 脚本会截断大文件、或漏传末尾 moov box,导致视频能加载但无法拖动/卡顿。真正可靠的验证是解析 MP4 容器结构。
ffprobe -v quiet -show_entries format=duration,bit_rate -of default=nw=1 video.mp4
如果报错 Invalid data found when processing input 或输出为空,则说明字节流不合法。更严格可加 -show_entries stream=codec_type,width,height 确认存在 video 流且参数合理。
最隐蔽的问题是:PHP 输出了完整 MP4 字节,但 Nginx/Apache 启用了 gzip 压缩(对二进制流绝对禁止),导致客户端收到乱码。务必在 Web 服务器配置中对 .mp4 或对应 PHP 路径禁用压缩。