getid3是PHP中读取音频元数据最可靠的库,能解析ID3、Vorbis Comment、MP4 atoms等,获取时长、码率、采样率等关键信息;需引入getid3.php,分析前确保文件存在且路径正确,避免依赖浏览器type或前端JS数据。

用 getid3 读取音频元数据最可靠
PHP 自带的 getimagesize() 只认图片,mime_content_type() 或 finfo 只能返回 MIME 类型(比如 audio/mpeg),拿不到时长、码率、采样率这些关键信息。真正能解析 ID3、Vorbis Comment、MP4 atoms 的,还是 getid3 库。
实操建议:
- 从 GitHub 下载最新版
getid3,解压后只需引入getid3.php即可,无需安装扩展 - 上传完成后,用临时路径初始化:
$getID3 = new getID3(); $info = $getID3->analyze('/tmp/phpABC123'); -
$info是完整数组,音频时长在$info['playtime_seconds'],格式在$info['fileformat'](如mp3、flac),码率在$info['audio']['bitrate'] - 注意:分析过程会读整个文件,大音频(>100MB)可能超时,建议配合
set_time_limit(0)或异步处理
finfo 能快速判断类型但不能读时长
如果只要区分 MP3/WAV/OGG 并验证安全性,finfo 比 getid3 快得多,且 PHP 默认启用。
常见错误现象:仅靠 $_FILES['audio']['type'] 判断类型——这由浏览器提供,完全不可信,容易被伪造。
立即学习“PHP免费学习笔记(深入)”;
正确做法:
- 用
finfo_open(FILEINFO_MIME_TYPE)读取真实 MIME:$finfo = finfo_open(FILEINFO_MIME_TYPE); $mimeType = finfo_file($finfo, $_FILES['audio']['tmp_name']); // 返回类似 'audio/mpeg'
- 白名单校验:
in_array($mimeType, ['audio/mpeg', 'audio/wav', 'audio/ogg']) - 不要依赖
finfo获取时长或编码参数——它不解析音频帧,返回的audio/x-wav和audio/wav还可能因系统 libmagic 版本不同而有差异
上传后立即读取失败?检查临时文件生命周期
PHP 上传的文件只在脚本执行期间保留在 $_FILES['audio']['tmp_name'],脚本结束即删除。很多开发者在重命名或移动前就调用 getid3->analyze(),结果报错 File does not exist。
必须确认:
- 分析操作要在
move_uploaded_file()之前完成,或传入已保存的永久路径 - 如果先
move_uploaded_file()再分析,确保目标目录有读权限,且 SELinux/AppArmor 没拦截(尤其 CentOS/Alpine) - Windows 下路径反斜杠可能引发问题,统一用
realpath()或str_replace('\', '/', ...)处理
Web 端已知时长,为什么服务端还要再查?
前端用 Audio.duration 或 FFmpeg.js 获取的时长,在服务端不具备可信度:用户可篡改 JS、伪造 POST 数据、跳过前端校验直接发请求。
关键点:
- 服务端必须独立验证,这是安全边界
-
getid3解析的是原始音频帧头和标签,比前端 JS 更准(例如某些 MP3 缺少 Xing header,JS 可能返回NaN) - 若业务需精确剪辑或转码,还应检查
$info['audio']['sample_rate']和$info['audio']['channels'],避免后续 FFmpeg 命令因参数不匹配失败
真正麻烦的是多音轨 MKV 或带封面的 M4A——getid3 能识别,但字段嵌套深,得一层层查 $info['tags']['id3v2'] 或 $info['moov']['udta']['meta'],别直接 print_r 就完事。



















