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

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

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

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

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

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

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

Ответ 1

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

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

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

Ответ 4

Я использовал 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

Ответ 5

Вот функция 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, '; '));
}

Ответ 6

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