php上传视频损坏需主动校验而非依赖$_files['error'],因error=0仅表示传输完成;应使用ffprobe检测文件结构完整性,配合最小大小限制等防护措施。

PHP处理上传的视频文件损坏,核心不是“报错”本身,而是识别损坏迹象并阻止其进入系统——因为PHP原生上传机制不会主动检测视频内容是否损坏,它只管把二进制流从临时目录移到目标位置。所谓“损坏报错”,通常是后续播放失败、转码崩溃或验证环节抛出的异常,而非$_FILES['error']返回非零值。
先确认是不是真损坏:区分上传失败和内容损坏
上传阶段的$_FILES['video']['error']为0(UPLOAD_ERR_OK),只代表文件完整抵达服务器临时目录,不保证视频结构合法。常见“看似上传成功实则损坏”的情况包括:
- 网络中断导致文件写入不全(但临时文件已生成,
error仍为0) - 客户端强制终止上传,临时文件残留且截断
- 浏览器或前端库对大视频分片上传未正确合并
- 视频编码异常(如头信息缺失、关键帧损坏),肉眼不可见但播放器无法解析
用FFmpeg校验视频完整性(推荐方案)
在move_uploaded_file()之后,调用系统FFmpeg命令快速探针检测,这是最可靠的内容级验证方式:
- 执行
ffprobe -v quiet -show_entries format=duration -of default=nw=1 "$file_path" - 若返回空或报错(如
No such file、Invalid data found),说明文件结构损坏或为空 - 可进一步检查流信息:
ffprobe -v error -show_entries stream=codec_type,width,height,duration -of default "$file_path"
PHP中示例:
if (exec("ffprobe -v quiet -show_entries format=duration -of default=nw=1 " . escapeshellarg($tmpPath), $output, $returnCode) && $returnCode !== 0) {unlink($tmpPath);
die("视频文件损坏,请重新上传");
}
补充性防护措施
单靠FFmpeg还不够,需组合策略降低风险:
-
限制最小文件大小:视频通常不小于几百KB,设
if ($file['size'] 直接拒绝 -
检查MIME与扩展名一致性:用
finfo_open(FILEINFO_MIME_TYPE)读真实类型,拒绝video/xxx但扩展名为.exe的文件 -
禁用可执行权限:存储目录设置
chmod 755,文件设为644,Web服务器配置禁止执行脚本 - 分离上传与处理流程:先存入待审目录,校验通过后再移入公开访问路径,避免损坏文件污染主资源库
前端配合减少损坏概率
服务端不能解决所有问题,前端也需规避常见诱因:
- 上传前用
File.size和File.type做初步过滤,拦截明显异常小文件 - 大视频启用分片上传(如tus.io协议),每片单独校验MD5,确保传输完整
- 禁用表单自动提交,改用
fetch或XMLHttpRequest监听upload.onprogress,超时或中断时主动清理 - 隐藏字段
<input type="hidden" name="MAX_FILE_SIZE" value="52428800">仅作客户端提示,不可信,服务端必须重复校验
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











