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

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

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

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

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

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

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

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

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

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

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

Я имею в виду, если файл имеет ожидаемый 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 и прослушивателе и загрузчике файлов и загрузчике файлов» по ​​адресу: http://www.galgani.it/software_repository/index.php

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