如何检查在PHP中上传的文件的文件types?

在PHP网站上,他们build议的唯一真正的检查是在这里使用is_uploaded_file()move_uploaded_file() 。 当然,由于各种原因,您通常不希望用户上传任何types的文件。

正因为如此,我经常使用一些“严格”的MIMEtypes检查。 当然,这是非常有缺陷的,因为经常MIMEtypes是错误的,用户不能上传他们的文件。 假冒和/或改变也很容易。 除此之外,每个浏览器和操作系统都以不同的方式处理它们。

另一种方法是检查扩展名,这当然比MIMEtypes更容易改变。

如果你只想要图像,使用像getimagesize()东西将工作。

其他types的文件呢? PDF,Word文档或Excel文件? 甚至文本只有文件?

编辑:如果您没有mime_content_type或Fileinfo和系统(“文件-bi $ uploadedfile”)给你错误的文件types,还有什么其他的select?

看看mime_content_type或Fileinfo 。 这些是内置的PHP命令,通过查看文件的内容来确定文件的types。 另外检查上面两页的评论,还有一些其他的好build议。

就个人而言,我使用了本质上是system("file -bi $uploadedfile")东西system("file -bi $uploadedfile") ,但我不确定这是否是最好的方法。

恕我直言,所有的MIMEtypes的检查方法是无用的。

假设你有哪些应该有MIMEtypes的application/pdf 。 标准方法试图find一个看起来像PDF标题的东西( %PDF- PDF或者像这样),他们将返回'好吧,看起来这是一个PDF文件'成功。 但实际上这并不意味着什么。 您可以上传仅包含%PDF-1.4的文件,并且将通过MIME检查。

我的意思是如果文件有一个预期的MIMEtypes – 它将总是通过MIMEtypes检查,否则结果是不确定的。

我假设你将有一个固定的白名单的文件types,你会接受。

对于这些types中的每一种,您将不得不使用不同的技术来validation它们是该格式的有效示例。

有两个相关的问题:

  • 它看起来大致像它可能是正确的types? (对于JPEG,您可以检查标题,对于许多基于Unix的格式,您可以检查“magic cookie”)。

  • 它实际上是这种types的一个有效的例子(例如对于任何类似XML的格式,您可以validation一个DTD。)

我认为,对于每种格式,您应该为每个格式提出不同的问题,因为与ZIP文件相比,PDF的答案会非常不同。

我使用了与PHP 5.2兼容的mime_content_type,因为我可以使用Fileinfo (它需要PHP 5.3)和system() ,它们都被我的提供者禁用。 例如,我检查一个文件是否是一个文本文件,所以:

 if (strcmp(substr(mime_content_type($f),0,4),"text")==0) { ... } 

您可以在我的“PHP目录和子目录监听器和文件查看器和下载器”中看到完整的示例: http : //www.galgani.it/software_repository/index.php

以下是来自iZend的函数file_mime_type:

 function file_mime_type($file, $encoding=true) { $mime=false; if (function_exists('finfo_file')) { $finfo = finfo_open(FILEINFO_MIME); $mime = finfo_file($finfo, $file); finfo_close($finfo); } else if (substr(PHP_OS, 0, 3) == 'WIN') { $mime = mime_content_type($file); } else { $file = escapeshellarg($file); $cmd = "file -iL $file"; exec($cmd, $output, $r); if ($r == 0) { $mime = substr($output[0], strpos($output[0], ': ')+2); } } if (!$mime) { return false; } if ($encoding) { return $mime; } return substr($mime, 0, strpos($mime, '; ')); } 
 if(isset($_FILES['uploaded'])) { $temp = explode(".", $_FILES["uploaded"]["name"]); $allowedExts = array("txt","htm","html","php","css","js","json","xml","swf","flv","pdf","psd","ai","eps","eps","ps","doc","rtf","ppt","odt","ods"); $extension = end($temp); if( in_array($extension, $allowedExts)) { //code.... } else { echo "Error,not Documentum type..."; } }