PHP 5.6 安全调用 FFmpeg 转 MP4 需满足三前提:ffmpeg 在 PATH 中、PHP 进程有文件读写权、exec 等函数未被禁用;必须用 escapeshellarg() 净化路径、固定参数防注入、输出目录隔离,并推荐 proc_open() 捕获错误。

PHP 5.6 本身不处理视频,转 MP4 完全依赖系统级 ffmpeg 命令。所谓“安全调用”,核心是防命令注入 + 权限隔离 + 输入净化,不是靠 PHP 版本新旧,而是靠写法和部署规范。
✅ 必须验证的三件事(缺一不可)
-
ffmpeg已安装且在$PATH中:终端执行which ffmpeg应返回路径(如/usr/bin/ffmpeg) - PHP 进程用户(如
www-data)对输入文件可读、对输出目录可写 -
exec、shell_exec等函数未被禁用:检查phpinfo()中disable_functions,确认不含exec,shell_exec,passthru,system
? 防命令注入的关键操作
不要拼接字符串,必须严格过滤路径和参数:
- 所有用户传入的文件路径(包括上传后的临时路径、目标路径)必须用
escapeshellarg()包裹 - 不要用
$_FILES['video']['tmp_name']直接拼命令,先move_uploaded_file()到受控目录,再用绝对路径调用 - 禁止让用户控制编解码器、分辨率等参数;如需自定义,只从白名单中选(如
scale=1280:-2固定写死,或从['1280x720', '640x360']中取值)
示例安全调用:
$input = escapeshellarg('/var/www/uploads/user_abc123.mp4');
$output = escapeshellarg('/var/www/converted/output.mp4');
// 固定参数,不暴露给用户
$cmd = "ffmpeg -y -i {$input} -vf scale=1280:-2 -crf 23 -preset medium -c:v libx264 -c:a aac {$output} 2>&1";
exec($cmd, $output_lines, $return_code);
if ($return_code !== 0) {
error_log("FFmpeg failed: " . implode("\n", $output_lines));
// 返回友好提示,不暴露路径或错误细节给前端
}⚠️ PHP 5.6 特别注意点
-
escapeshellarg()和escapeshellcmd()在 5.6 中完全可用,但不能替代输入校验 -
proc_open()支持良好,比exec()更利于捕获实时错误(推荐用于生产) -
disable_functions在共享主机上常被锁死,若exec返回空或null,大概率是被禁用——此时只能换云服务(如 Cloudinary、AWS MediaConvert)或改用异步任务队列(如 Beanstalkd + worker 脚本)
?️ 补充安全加固建议
- 输出目录不要放在 Web 可访问路径下(如
/var/www/html/convert/),应放于/var/www/private/converted/,并通过 PHP 代理下载 - 设置
open_basedir限制 PHP 只能访问指定目录,防止路径穿越 -
ffmpeg进程运行用户应与 Web 用户分离(如用ffmpeg-user账号跑命令,PHP 通过sudo -u ffmpeg-user调用,配合visudo白名单授权) - 对上传文件做二次校验:用
ffprobe检查是否真为视频(ffprobe -v quiet -print_format json -show_entries format=duration,input_filename input.mp4),拒绝非视频文件
不复杂但容易忽略
立即学习“PHP免费学习笔记(深入)”;



















