Меню
безкоштовно
Головна  /  Поради / Php як за змістом визначити тип файлу. Розширення файлу засобами PHP

Php як за змістом визначити тип файлу. Розширення файлу засобами PHP

Остання лінія близька. Ви можете використовувати: if (mime_content_type ($ _ FILES [ "fupload"] [ "tmp_name"]) \u003d\u003d "image / gif") (...

У разі, коли я зараз працюю, мій $ _FILES .. [ "type"] повідомляє себе як «text / csv», в той час як mime_content_type () і finfo () (пропоновані іншими) повідомляють «text / plain». , Як зазначає @deceze, $ _FILES .. [ "type"] корисно тільки знати, який тип клієнт вважає файлом.

ПОПЕРЕДЖЕННЯ : Таку відповідь фактично не перевіряє тип файлу. Він перевіряє тільки ім'я. він не підходить для реальних цілей безпеки.

EDIT: не використовуйте цей метод, оскільки він не виконує перевірку безпеки. Я залишаю цю відповідь тут, щоб ніхто не робив таку ж помилку, як я, намагаючись це зробити.

Я спробував наступне, і це спрацювало для мене:

$ Allowed \u003d array ( "gif", "png", "jpg", "pdf"); $ Filename \u003d $ _FILES [ "input_tag_name"] [ "name"]; $ Ext \u003d pathinfo ($ filename, PATHINFO_EXTENSION); if (! in_array ($ ext, $ allowed)) (echo "error";)

У PHP 5.5 я використовую цю функцію для отримання типу файлу і перевіряю, чи є зображення:

Function getFileType ($ file) (return image_type_to_mime_type (exif_imagetype ($ file));) // Get file type $ file_type \u003d getFileType ( "path / to / images / test.png"); echo $ file_type; // Prints image / png // 1. All images have mime type starting with "image" // 2. No other non-image mime types contain string "image" in it

Тоді ви могли б зробити:

If (strpos ($ filetype, "image")! \u003d\u003d false) (// This is an image)

Це простий сценарій з одним рядком, який я часто використовую.

$ Image \u003d "/var/www/Core/temp/image.jpg"; $ IsImage \u003d explode ( "/", mime_content_type ()) \u003d\u003d "image";

В основному я використовую mime_content_type (), щоб отримати щось на зразок «image / jpg», а потім зламати його «/» і перевірити на перший елемент масиву, щоб побачити, чи говорить він «образ».

Сподіваюся це працює!

Звичайно, ви можете перевірити, чи є це зображення з exif, але кращий спосіб, Я думаю, це зробити з finfo наступним чином:

$ Allowed_types \u003d array ( "application / pdf", "image / jpeg", "image / png"); $ FileInfo \u003d finfo_open (FILEINFO_MIME_TYPE); $ Detected_type \u003d finfo_file ($ fileInfo, $ _FILES [ "datei"] [ "tmp_name"]); if (! in_array ($ detected_type, $ allowed_types)) (die ( "Please upload a pdf or an image");) finfo_close ($ fileInfo);

На додаток до @deceze ви також можете finfo () перевірити MIME-тип файлів без зображення:

$ Finfo \u003d new finfo (); $ FileMimeType \u003d $ finfo-\u003e file ($ path. $ Filename, FILEINFO_MIME_TYPE);

Function assignFilePreviews () ($ ( "input"). Change (function () (var prvCnt \u003d $ (this) .attr ( "data-preview-container"); if (prvCnt) (if (this.files && this. files) (var reader \u003d new FileReader (); reader.onload \u003d function (e) (var img \u003d $ ( " "); Img.attr (" src ", e.target.result); img.error (function () ($ (prvCnt) .html (" ");)); $ (prvCnt) .html (" ") ; img.appendTo (prvCnt);) reader.readAsDataURL (this.files);))));) $ (document) .ready (function () (assignFilePreviews ();));

Це також обробляє випадок, коли обраний файл з неприпустимим типом (наприклад, pdf)

8 відповідей 8

Ніколи не використовуйте $ _FILES .. [ "type"]. Інформація, що міститься в ньому інформація взагалі не перевіряється, це призначене для користувача значення. Перевірте тип самостійно. Для зображень exif_imagetype зазвичай є хорошим вибором:

$ AllowedTypes \u003d array (IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF); $ DetectedType \u003d exif_imagetype ($ _ FILES [ "fupload"] [ "tmp_name"]); $ Error \u003d! In_array ($ detectedType, $ allowedTypes); $ Size \u003d getimagesize ($ filename); if ($ size \u003d\u003d\u003d false) (throw new Exception ( "($ filename): Invalid image.");) if ($ size\u003e 2500 || $ size\u003e 2500) (throw new Exception ( "($ filename) : Image too large. ");) if (! $ img \u003d @imagecreatefromstring (file_get_contents ($ filename))) (throw new Exception (" ($ filename): Invalid image content. ");)

Перевірка по getimagesize () запобігає деяким DoS-атаки, тому що нам не потрібно намагатися виконати imagecreatefromstring () з кожного наданого користувачем файлу, який не є файлом зображення або файлом занадто великого розміру. На жаль, згідно з документами PHP не може бути покладатися на перевірку вмісту типу зображення.

imagecreatefromstring (), нарешті, намагається відкрити файл як зображення - якщо це успішно - у нас естьізображеніе.

2017-07-12 09: 05: 07Z

Це простий однорядковий скрипт, який я часто використовую.

$ Image \u003d "/var/www/Core/temp/image.jpg"; $ IsImage \u003d explode ( "/", mime_content_type ()) \u003d\u003d "image";

Зазвичай я використовую mime_content_type (), щоб отримати щось на зразок «image / jpg», а потім підриваю його за допомогою «/» і перевіряю перший елемент масиву, щоб побачити, чи говорить він «image».

Я сподіваюся, що це працює!

2017-10-18 22: 53: 49Z

У PHP 5.5 я використовую цю функцію для отримання типу файлу і перевірки, якщо зображення:

Function getFileType ($ file) (return image_type_to_mime_type (exif_imagetype ($ file));) // Get file type $ file_type \u003d getFileType ( "path / to / images / test.png"); echo $ file_type; // Prints image / png // 1. All images have mime type starting with "image" // 2. No other non-image mime types contain string "image" in it

Тоді ви можете зробити:

If (strpos ($ filetype, "image")! \u003d\u003d false) (// This is an image)

Повний список типів пантоміми: http: //www.sitepoint .com / веб-фонди / MIME типи-повний-лист /

2015-06-11 16: 47: 46Z

Останній рядок близька. Ти можеш використовувати: if (mime_content_type ($ _ FILES [ "fupload"] [ "tmp_name"]) \u003d\u003d "image / gif") (... р\u003e

У разі, над яким я зараз працюю, мій $ _FILES .. [ "type"] повідомляє про себе як "text / csv", в той час як mime_content_type () і finfo () (запропоновані іншими) повідомляють "text / plain. ". Як вказує @deceze, $ _FILES .. [ "type"] корисно знати тільки про те, якого типу клієнт вважає файл.

2018-08-09 19: 38: 14Z

ПОПЕРЕДЖЕННЯ: Таку відповідь фактично не перевіряє тип файлу. Він тільки перевіряє ім'я. він не підходить для реальних цілей безпеки.

РЕДАКТИРОВАТЬ: не використовуйте цей метод, Так як він не виконує перевірку безпеки. Я залишаю цю відповідь тут, щоб ніхто не робив таку ж помилку, як я, намагаючись це зробити.

Я спробував наступне, і це спрацювало для мене.

Завдання визначення розширення виникає в розробці досить часто - тут і, і аналіз наявних файлів, і пошук файлу. У роботі з файлами на сервері, є так само часте рішення збереження файлу не з вихідним ім'ям, а призначення в якості імені файлу поточного значення TIMESTAMP сервера. Рішень у цій задачі існує чимало для різних мов програмування. Хоча деякі рішення, в першу чергу, що приходять на розум, іноді доводиться допрацьовувати через те розмаїття імен файлів які тільки можуть бути. Для файлу з ім'ям "myfile.txt" можна сміливо запропонувати розбити рядок на частини розділені крапкою і взяти останню. Але що робити з файлами "my.file.txt" або в разі, якщо розширення не вказано "myfile"?

У цій статті, розглянемо такі рішення.

Для зручності ім'я файл задамо в строкової змінної:


$ Filename \u003d "myfile.txt";

// інші варіанти імені файлу
$ Filename \u003d "File"; // не вказано розширення
$ Filename \u003d "my.file.txt"; // точка в імені файлу
$ Filename \u003d "dir / myfile.txt"; // ім'я файлу із зазначенням директорії
?>

Найпростіше і зручний, на мій погляд, рішення використовувати функцію pathinfo (), яка поверне асоційований масив, який містить відомості повному імені, розширенні і директорії файлу. Після цього залишається тільки вивести необхідний елемент масиву.



$ File_info \u003d pathinfo ($ filename);
return $ file_info [ "extension"];
}


?>

Щоб не робити власну функцію можна вблагати код, вказавши в якості другого параметра значення PATHINFO_EXTENSION. У цьому випадку функція поверне не весь масив, а тільки значення розширення.


echo pathinfo ($ filename, PATHINFO_EXTENSION);
?>

Обидва варіанти коректно повернуть значення розширення "txt", крім випадку, де розширення не вказано. Там, де розширення немає, буде повернута порожній рядок.

Це рішення є для PHP, починаючи з версії 4.0.3.


Якщо з причин версії PHP або будь-якої іншої причини це рішення не є, можна використовувати традиційне рішення - розбивку рядки імені файлу на частини між точками, вважаючи, що остання ділянка і буде розширенням.


function get_file_extension ($ filename) (
return end (explode ( ".", $ filename));
}

echo get_file_extension ($ filename);
?>

Тут, функція explode () розбиває рядок на масив із символів, між якими ставлять крапку, а функція end () повертає останній елемент отриманого масиву.

У цьому прикладі, якщо розширення не задано явно, тобто точки в імені файлу немає, буде повернуто вихідне ім'я файлу. У разі, якщо розширення є, воно буде отримано коректно.

22

Зверніть увагу, що вам може не знадобитися використання розширень файлів для визначення типу файлу. наприклад, для завантаження файлу з расшіреніем.png .Міні-тип також може бути легко підроблений шкідливим клієнтом для передачі в якості зображення. Спираючись на цю інформацію, це ризик для безпеки.

Для розміру файлу, ви вже використовуєте $ _FILES [ "imagefile"] [ "size"]; це нормально, я думаю, але ви будете знати це тільки в тому випадку, коли файл був завантажений. Тим не менше, немає реального способу перевірити це, перш ніж завантажувати, я боюся ...

Ви може знайти JS-код для першої попередньої перевірки розширення до того, як файл буде завантажений, але вам все одно доведеться перевіряти серверну сторону, оскільки все, що робиться на стороні клієнта, за своєю суттю небезпечно.

Не впевнений, що ви можете зробити те ж саме щодо розміру файлу, хоча ...

Деякі браузери можуть підтримувати приховане поле під назвою MAX_FILE_SIZE (див. Документацію про file upload); але не впевнений, що це дійсно підтримується (ніколи не бачив раніше, насправді, так що, ймовірно, не :-()

Як Зауваження, ви, ймовірно, захочете налаштувати upload_max_filesize, так що дозволяє завантажувати принаймні, великий як ви хочете (за замовчуванням він зазвичай встановлений в 2 МБ, тому він повинен бути в порядку)

2

Php це мова сценаріїв на стороні сервера, і якщо зображення знаходяться на стороні клієнта, ви не можете перевірити їх розмір перед завантаження через PHP .

2

Вам потрібно дві речі:

ваше розширення перевірка регістронезавісімого:

If ($ strtolower ($ ext \u003d\u003d "jpg")) (// do your stuff)

Перевірте, якщо файл насправді містить зображення. Найпростіший спосіб зробити це FileInfo:

$ Finfo \u003d finfo_open (FILEINFO_MIME_TYPE); echo finfo_file ($ finfo, $ filename); $ Finfo_close ($ finfo);

Альтернативний спосіб перевірки, чи є файл насправді зображення завантажується в бібліотеці зображень, як Gd. Якщо ваш файл можна успішно завантажити, це зображення.

Майте на увазі, що зображення jpeg можуть мати лібо.jpg, або расшіреніе.jpeg.

3

Ось що я роблю:

If ($ _ FILES [ "userPicture"] [ "error"] \u003d\u003d 0) (// File was uploaded ok, so it "s ok to proceed with the filetype check. $ Uploaded_type \u003d exif_imagetype ($ _ FILES [" userPicture "] [ "tmp_name"]); // What we have now is a number representing our file type. switch ($ uploaded_type) (case "1": $ uploaded_type \u003d "gif"; break; case "2": $ uploaded_type \u003d " jpg "; break; case" 3 ": $ uploaded_type \u003d" png "; break;))

Edit: Це має перевагу роботи «в будь-якому браузері», тому що він не залежить від імені файлу, або що-небудь користувач поставляється, крім «помилки» значення файлів масиву, який говорить нам, що не було дійсно помилка.

Що таке MIME-тип файлу? Як визначити MIME-тип файлу засобами PHP? Як встановити модуль Fileinfo і налаштувати локальний сервер, збірка Денвер.

MIME - стандарт, що описує передачу різних типів даних по електронній пошті, А також специфікація для кодування інформації і форматування повідомлень таким чином, щоб їх можна було пересилати через Інтернет.

учи матчасть

Як такий, визначення MIME-типу того чи іншого файлу будується на основі його (файлу) розширення. Як ви розуміє, це досить умовне визначення MIME-типу. Наприклад, файлу image.jpg (навіть якби він був чимось іншим), по розширенню jpg, буде визначений MIME-тип: image / jpeg. Звичайно, можна проаналізувати зміст файлу і на його основі визначити правильний MIME-тип, але дане рішення не входить в рамки моєї замітки.

Головне, що зараз потрібно зрозуміти, так це необхідність наявності серверного magic.mime файлу, де описуються MIME-типи. Як такий, він входить до складу PHP. Буває, що і в папках сервера Apache можна знайти цей файл. Загалом, хто шукає, той знайде. За ідеєю, дізнатися, де знаходиться magic.mime можна прочитавши значення опції mime_magic.magicfile з php.ini. наприклад:

Однак у мене ця опція нічого не повертає, проте - спробуйте.

Слід зазначити, для того, щоб визначити MIME-тип файлу, в PHP є модуль Fileinfo. Іншими словами, ви завжди можете зорієнтуватися, чи є у вас можливість щось дізнатися чи ні, за наявністю цього модуля. наприклад:

Так що якщо модуль є, то є і шанс, що воно все буде працювати. В крайньому випадку, можна вказати шлях до свого magic.mime файлу.

Практика

самим простим способом визначення MIME-типу файлу засобами PHP є використання php-функції mime_content_type () з модуля Fileinfo. наприклад:

В результаті ми повинні отримати рядок: image / jpeg. Звичайно, якщо файл image.jpg - існує, модуль Fileinfo підключений і magic.mime доступний.

Зверніть увагу, що значення функції mime_content_type () має являти собою повний шлях і ім'я файлу, для чого я використовував конструкцію dirname (__ FILE__). "Image.jpg". Також слід пам'ятати, що ця функція вважається застарілою (англ. deprecated) І в подальшому буде виключена з PHP. Альтернативою може служити рішення, написане з використанням php-функцій з того ж Fileinfo модуля:

Тут, функція finfo_open () створює Fileinfo ресурс ($ finfo). З урахуванням константи FILEINFO_MIME_TYPE, доступною в PHP версії не нижче 5.3.0, ми зможемо отримати MIME-тип файлу (-ів).

Думаю, вже зрозуміло, що php-функція finfo_file (), використовуючи Fileinfo ресурс ($ finfo), повертає нам інформацію для вказаного файлу ($ Filename). У нашому випадку це MIME-тип: image / jpeg.

Ну і якщо все вище сказане не принесло результату, можна написати свій парсер. Тут теж багато варіантів. Одним з таких є парсер magic.mime файлу. Не важливо де він знаходиться, головне щоб він був.

Думаю, розписувати, що й до чого тут не має сенсу - і так все більш ніж зрозуміло. Хочу лише звернути вашу увагу на вказаний мною шлях до файлу mime.types. Як ви вже напевно здогадалися, мова йде про локальному сервері. Ще точніше, про збірку Денвер. І ось тут, ми плавно переходимо до установки модуля та налаштування сервера.

Встановлення та налаштування

Ще раз нагадаю: мова йде про локальному сервері, збірка Денвер. Як ви розуміє, нам знадобиться звернутися до файлу php.ini. У мене він знаходиться в папці: З: \\ WebServer \\ usr \\ local \\ php5 \\. У ньому нам треба підключити два розширення: php_fileinfo.dll і php_mime_magic.dll. Наприклад, так:

Extension \u003d php_fileinfo.dll extension \u003d php_mime_magic.dll

Звертаю увагу на те, що дані розширення повинні існувати. У мене вони знаходяться в папці: З: \\ WebServer \\ usr \\ local \\ php5 \\ ext \\.

Mime_magic.debug \u003d On mime_magic.magicfile \u003d "C: \\ WebServer \\ usr \\ local \\ apache \\ conf \\ magic.mime"

Зверніть увагу, що для опції mime_magic.magicfile потрібно прописати повний шлях і ім'я migic.mime. Ось власне і все.