Как проверить типы файлов загруженных файлов в PHP?


На веб-сайте PHP единственная реальная проверка, которую они предлагают, - это использование is_uploaded_file() или move_uploaded_file(), здесь. Конечно, обычно вы не хотите, чтобы пользователь загружал файлы любого типа по целому ряду причин.

Из-за этого я часто использовал некоторую "строгую" проверку типа mime. Конечно, это очень неправильно, потому что часто типы mime неверны, и пользователи не могут загрузить свой файл. Это также очень легко подделать и/или изменить. И наряду со всем этим, каждый браузер и операционная система имеют дело с ними иначе.

Другой метод - проверить расширение, которое, конечно, еще проще изменить, чем тип mime.

Если вам нужны только изображения, будет работать что-то вроде getimagesize().

Как насчет других типов файлов? PDF-файлы, документы Word или файлы Excel? Или даже только текстовые файлы?

Редактировать: Если у вас нет mime_content_type или Fileinfo, а система ("файл -bi $загруженный файл") выдает неправильный тип файла, какие еще варианты там?

Author: Alix Axel, 2008-11-22

6 answers

Взгляните на mime_content_type или Fileinfo. Это встроенные команды PHP для определения типа файла путем просмотра содержимого файла. Также проверьте комментарии на двух вышеуказанных страницах, есть и другие хорошие предложения.

Лично мне повезло использовать что-то, что по сути является system("file -bi $uploadedfile"), но я не уверен, что это лучший метод.

 32
Author: davr, 2008-11-22 02:20:52

ИМХО, все методы проверки типа MIME бесполезны.

Скажите, что у вас есть то, что должно иметь тип MIME application/pdf. Стандартные методы пытаются найти что-то похожее на заголовок PDF (%PDF- или что-то в этом роде. вот так), и они вернут "Хорошо, похоже, что это файл PDF" в случае успеха. Но на самом деле это ничего не значит. Вы можете загрузить файл, содержащий только %PDF-1.4, и он пройдет MIME-проверку.

Я имею в виду, что если файл имеет ожидаемый тип MIME - он всегда будет передавать Проверка типа MIME, в противном случае результат не определен.

 13
Author: Sudden Def, 2012-02-24 11:23:38

Я предполагаю, что у вас будет фиксированный белый список типов файлов, которые вы примете.

Для каждого из этих типов вам придется использовать различные методы, чтобы убедиться, что они являются допустимыми примерами этого формата.

Есть два связанных вопроса:

  • Похоже ли это примерно на то, что это может быть правильный тип? (Для JPEG вы можете проверить заголовки, как вы уже упоминали. Для многих форматов на базе Unix вы можете проверить "волшебный файл cookie".)

  • Действительно ли это допустимый пример такого типа (например, для любого формата, подобного XML, вы можете проверить соответствие DTD.)

Я думаю, что для каждого формата вы должны задавать отдельные вопросы для каждого из них, потому что ответ будет совершенно иным для PDF-файлов по сравнению с ZIP-файлами.

 2
Author: Oddthinking, 2008-11-22 02:34:00

Я использовал mime_content_type, совместимый с PHP 5.2, потому что я не могу использовать ни 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

 2
Author: Francesco Galgani, 2012-04-26 07:01:19

Вот функция file_mime_type из iZend:

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, '; '));
}
 1
Author: iZend, 2013-06-27 17:17:54
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...";
    }
}
 1
Author: Krausz Lóránt Szilveszter, 2017-08-10 08:20:43