如何针对其扩展名验证文件类型?

时间:2015-11-13 14:35:56

标签: php mime-types mime file-type

我想创建一个上传器脚本,我想定义一些允许上传的文件类型,以防止通过重命名我使用此数组的文件扩展名来获取技巧:PHP / Mime Types - List of mime types publically available? 首先它检查是否允许文件扩展名(例如.xsl)然后它使用finfo来获取mimtype以检查该数组以查看mimetype是否与扩展名匹配。

我上传了一个.xsl文件,finfo将文件类型作为application / octet-stream重新编译,但xsl扩展名的数组返回application / x-msexcel,因此它不会相等而不会被验证。

我是否真的忘记了mimetype与脚本的文件扩展名验证器匹配,我应该检查文件扩展名?或者我该怎么办?

1 个答案:

答案 0 :(得分:1)

基本上你做得对。你永远不应该依赖从上传表单发送的mime类型标题,因为你可以轻易地伪造它或它不存在,那么你经常会得到application/octet-stream标题。

因此,检查文件扩展名是否与此文件扩展名的允许mime类型匹配是一种好方法。

我看到你链接了这个列表here。这肯定是一个很好的列表,但不适用于php,因为在数组中有太多的ovverriden,例如:

$mimeTypes = array(
    'xlm' => 'application/vnd.ms-excel',//overridden
    'xlm' => 'application/x-excel',
    'xls' => 'application/excel',//overridden
    'xls' => 'application/vnd.ms-excel'
);

var_dump( $mimeTypes );

这只会输出两个值而不是四个,你应该使用这样的数组:

$mimeTypes = array(
    'xlm' => array( 'application/vnd.ms-excel', 'application/x-excel' ),
    'xls' => array( 'application/excel', 'application/vnd.ms-excel' ),
    'txt' => array( 'text/plain' )
);

var_dump( $mimeTypes );

因此,如果您已经拥有文件扩展名,则只需使用in_array()检查mimetype。

这是您可以解决的基本示例。 注意:这不是一个有效的例子,但我想您知道我想指出的地方:

// you have your file, you said it´s excel but you uploaded it with extension txt
$filepath = "excel.txt";

if( strpos( $filepath, '.' ) === false ) {
    // no file extension
    // return ?
}
// get the file extension
// well there is surely a better way
$filenameParts = explode( ".", $filepath );
$fileExt = array_pop( $filenameParts );// return the las element of the array and REMOVES it from the array

// your fopen stuff to get the mime type
// ok let´s say we are getting back the follwing mime type
$fileMimeType = 'application/vnd.ms-excel';

// now check if filextension is in array and if mimetype for this extension is correct
if( isset( $mimeTypes[$fileExt] ) && in_array( $fileMimeType, $mimeTypes[$fileExt] ) ) {
    // file extension is OK AND mime type matches the file extension
} else {
    // not passed unknown file type, unknown mime type, or someone tricked you
    // your excel.txt should end up here
}