我想创建一个上传器脚本,我想定义一些允许上传的文件类型,以防止通过重命名我使用此数组的文件扩展名来获取技巧:PHP / Mime Types - List of mime types publically available? 首先它检查是否允许文件扩展名(例如.xsl)然后它使用finfo来获取mimtype以检查该数组以查看mimetype是否与扩展名匹配。
我上传了一个.xsl文件,finfo将文件类型作为application / octet-stream重新编译,但xsl扩展名的数组返回application / x-msexcel,因此它不会相等而不会被验证。
我是否真的忘记了mimetype与脚本的文件扩展名验证器匹配,我应该检查文件扩展名?或者我该怎么办?
答案 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
}