首页 文章

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

提问于
浏览
46

在PHP网站上,他们建议的唯一真实检查是使用 is_uploaded_file()move_uploaded_file()here . 当然,出于各种原因,您通常不会上传任何类型的文件 .

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

另一种方法是检查扩展,当然比mime类型更容易改变 .

如果你只想要图像,使用 getimagesize() 这样的东西就行了 .

那么其他类型的文件呢? PDF,Word文档或Excel文件?甚至是文本文件?

Edit: 如果您没有mime_content_typeFileinfo且系统("file -bi $uploadedfile")为您提供了错误的文件类型,还有哪些其他选项?

6 回答

  • 1

    看看mime_content_typeFileinfo . 这些是内置的PHP命令,用于通过查看文件的内容来确定文件的类型 . 另外还要检查上面两页的评论,还有一些其他好的建议 .

    就个人而言've had good luck using something that's本质上是 system("file -bi $uploadedfile") ,但我是最好的方法 .

  • 2

    恕我直言,所有MIME类型的检查方法都没用 .

    假设你有哪个应该有MIME类型 application/pdf . 标准方法试图找到看起来像PDF Headers 的东西( %PDF- 或类似的那样),并且成功时它们将返回'Okay, seems like this is a PDF file' . 但实际上这并不意味着什么 . 您可以上传仅包含 %PDF-1.4 的文件,它将通过MIME检查 .

    我的意思是如果文件具有预期的MIME类型 - 它将始终传递MIME类型检查,否则结果是未定义的 .

  • 2

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

    对于这些类型中的每一种,您将不得不使用不同的技术来验证它们是该格式的有效示例 .

    有两个相关的问题:

    • 它看起来大致可能是正确的类型吗? (对于JPEG,您可以检查 Headers ,正如您所提到的 . 对于许多基于Unix的格式,您可以检查“魔术cookie” . )

    • 它实际上是该类型的有效示例(例如,对于任何类似XML的格式,您可以针对DTD进行验证 . )

    我认为,对于每种格式,您应该为每种格式提出单独的问题,因为与ZIP文件相比,PDF的答案将大不相同 .

  • 13

    我使用了与PHP 5.2兼容的mime_content_type,因为我既不能使用 Fileinfo (它需要PHP 5.3),也不能使用 system() ,我的提供者禁用了它 . 例如,我检查文件是否是文本文件,因此:

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

    你可以在我的"PHP Directory and Subdirectory Listener & File Viewer and Downloader"中看到一个完整的例子:http://www.galgani.it/software_repository/index.php

  • 32
    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...";
        }
    }
    
  • 2

    这是来自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, '; '));
    }
    

相关问题