Вопрос

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

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

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

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

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

Редактировать: Если у вас нет mime_content_type или Информация о файле и system("file -bi $uploadedfile") выдает неправильный тип файла, какие еще есть варианты?

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

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

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

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

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

Я использовал mime_content_type, который совместим с PHP 5.2, потому что я не могу использовать ни Fileinfo (для этого требуется PHP 5.3), ни system () , которые отключены моим провайдером , Например, я проверяю, является ли файл текстовым файлом, так:

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

Полный пример вы можете увидеть в моем " Слушателе каталога и подкаталогов PHP & amp; Средство просмотра файлов и загрузчик " в: http://www.galgani.it/software_repository/index.php

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

Вот функция 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, '; '));
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top