在PHP项目中处理文件上传或者文件校验场景时,判断一个文件是否为视频文件是常见需求,下面介绍几种常用的检测方式。

方法一:通过文件扩展名判断
这种方式是最简单的检测方式,通过获取文件的后缀名,和预设的视频扩展名列表做匹配,不过这种方式很容易被伪造,只能作为初步筛选。
<?php
/**
* 通过扩展名判断是否为视频文件
* @param string $filePath 文件路径
* @return bool
*/
function isVideoByExtension($filePath) {
// 常见视频扩展名列表
$videoExtensions = ['mp4', 'avi', 'mov', 'mkv', 'flv', 'wmv', 'rmvb', '3gp', 'webm'];
// 获取文件扩展名并转为小写
$extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
return in_array($extension, $videoExtensions);
}
// 测试示例
$testFile = 'test.mp4';
var_dump(isVideoByExtension($testFile)); // 输出 bool(true)
?>
方法二:通过MIME类型判断
可以通过PHP的finfo扩展获取文件的MIME类型,视频文件的MIME类型通常以video/开头,这种方式比扩展名检测更可靠。
<?php
/**
* 通过MIME类型判断是否为视频文件
* @param string $filePath 文件路径
* @return bool
*/
function isVideoByMime($filePath) {
if (!file_exists($filePath)) {
return false;
}
// 打开finfo资源
$finfo = finfo_open(FILEINFO_MIME_TYPE);
// 获取文件MIME类型
$mimeType = finfo_file($finfo, $filePath);
finfo_close($finfo);
// 判断MIME类型是否以video/开头
return strpos($mimeType, 'video/') === 0;
}
// 测试示例
$testFile = 'test.mp4';
var_dump(isVideoByMime($testFile)); // 输出 bool(true)
?>
方法三:结合扩展名和MIME类型双重校验
为了提升检测的准确性,可以将扩展名和MIME类型检测结合起来,同时校验两项都符合视频文件的特征,减少误判概率。
<?php
/**
* 结合扩展名和MIME类型判断是否为视频文件
* @param string $filePath 文件路径
* @return bool
*/
function isVideoCombined($filePath) {
if (!file_exists($filePath)) {
return false;
}
// 扩展名校验
$videoExtensions = ['mp4', 'avi', 'mov', 'mkv', 'flv', 'wmv', 'rmvb', '3gp', 'webm'];
$extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
if (!in_array($extension, $videoExtensions)) {
return false;
}
// MIME类型校验
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $filePath);
finfo_close($finfo);
return strpos($mimeType, 'video/') === 0;
}
// 测试示例
$testFile = 'test.mp4';
var_dump(isVideoCombined($testFile)); // 输出 bool(true)
?>
三种方式对比
下面通过表格对比三种检测方式的特点,方便开发者根据场景选择:
| 检测方式 | 实现难度 | 准确率 | 适用场景 |
|---|---|---|---|
| 扩展名检测 | 低 | 低 | 仅做初步筛选,对安全性要求不高的场景 |
| MIME类型检测 | 中 | 中 | 普通文件上传校验场景 |
| 双重校验 | 中 | 高 | 对文件合法性要求较高的上传场景 |
注意事项
- 使用
finfo扩展前需要确保PHP已经开启该扩展,大部分默认环境已经开启,若未开启可以在php.ini中配置开启。 - 如果上传的文件是用户伪造的,即使双重校验也可能存在漏判情况,若对安全性要求极高,可以结合视频解析库进一步校验文件内容是否可正常解析。
- 检测前需要先判断文件是否存在,避免函数执行报错。