我想创建一个上传器脚本,我想定义一些允许上传的文件类型,通过重命名文件扩展名来防止作弊。我使用这个数组:PHP/Mime types-公共可用的Mime类型列表?首先,它检查是否允许文件扩展名(例如.xsl),然后使用finfo获取mimtype来检查该数组,看看mimetype是否与扩展名匹配。
我上传了一个.xsl文件,finfo将文件类型重新运行为application/octet流,但xsl扩展名的数组返回application/x-mexcel,因此它将不相等,也不会被验证。
我真的应该忘记mimetype与脚本的文件扩展名验证器的匹配吗?我应该只检查文件扩展名吗?或者我该怎么办?
基本上你做得对。你永远不应该依赖从上传表单发送的mime类型的头,因为你可以很容易地伪造它,或者它不存在,那么你通常会得到application/octet-stream
头。
因此,检查文件扩展名是否与该文件扩展名允许的mime类型匹配将是一个很好的方法。
我看到你在这里链接了这个列表。这当然是一个很好的列表,但对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
}