
В PHP для проверки типа загружаемого файла чаще всего используют массив $_FILES, который содержит ключи name, type, tmp_name, error и size. Тип файла, получаемый через $_FILES[‘file’][‘type’], определяется на основе MIME-типа, передаваемого клиентом, что делает прямую проверку ненадёжной для защиты от вредоносных файлов.
Для точного определения расширения рекомендуется использовать функцию pathinfo(), которая возвращает массив с ключами dirname, basename, extension и filename. Проверка расширения через pathinfo($filename, PATHINFO_EXTENSION) позволяет фильтровать файлы по списку допустимых форматов, например [‘jpg’,’png’,’pdf’].
Дополнительно безопаснее использовать finfo_file() или mime_content_type() для получения реального MIME-типа содержимого файла. Это снижает риск обхода проверки путем переименования расширения и обеспечивает соответствие содержимого заявленному формату.
При организации загрузки файлов на сервер следует сочетать проверку расширения, MIME-типа и размера файла. Такой подход минимизирует вероятность загрузки вредоносных скриптов и упрощает обработку данных на стороне сервера.
Использование функции mime_content_type для проверки типа файла

Функция mime_content_type возвращает MIME-тип файла на основе его содержимого. Она полезна для проверки соответствия загруженного файла допустимым типам перед сохранением на сервере.
Простейший пример использования:
$type = mime_content_type(‘example.pdf’);
echo $type; // application/pdf
Рекомендуется проверять MIME-тип, а не только расширение файла, так как расширение легко подделать. Например, файл с расширением .jpg может быть на самом деле текстовым документом.
Для ограниченного набора допустимых типов можно использовать массив и функцию in_array:
$allowed = [‘image/jpeg’, ‘image/png’, ‘application/pdf’];
if (in_array(mime_content_type($file), $allowed)) {
echo ‘Файл допустим’;
} else {
echo ‘Недопустимый тип файла’;
}
Внимание: mime_content_type зависит от системной библиотеки fileinfo. На серверах без этой библиотеки функция может возвращать FALSE. В таких случаях используйте finfo_open и finfo_file для точного определения типа файла.
Практическая рекомендация: всегда проверяйте MIME-тип вместе с расширением, особенно при загрузке изображений и документов, чтобы исключить попытки загрузки вредоносных файлов.
Проверка расширения файла через pathinfo

Функция pathinfo() возвращает массив с информацией о пути к файлу, включая имя файла, расширение и директорию. Для проверки расширения достаточно обратиться к ключу ['extension'].
Пример проверки расширения:
$file = 'document.pdf';
$ext = pathinfo($file, PATHINFO_EXTENSION);
if (in_array(strtolower($ext), ['jpg','png','gif'])) {
echo 'Файл разрешён';
} else {
echo 'Неподдерживаемый формат';
}
Использование strtolower() гарантирует корректное сравнение независимо от регистра расширения. Рекомендуется заранее формировать список допустимых расширений в массиве, чтобы упрощать поддержку и добавление новых форматов.
Для файлов, загруженных через $_FILES, проверку расширения следует совмещать с проверкой MIME-типа, чтобы исключить подмену формата через переименование.
При работе с пользовательскими данными важно избегать прямого использования расширения для сохранения файла на сервере без валидации, чтобы снизить риск выполнения вредоносного кода.
Сравнение MIME-типа с разрешёнными форматами
Для проверки загружаемых файлов в PHP важно использовать MIME-тип, а не только расширение. Расширение можно подделать, а MIME-тип, определяемый функцией finfo_file() или через $_FILES['file']['type'], точнее отражает содержимое файла.
Создайте массив допустимых MIME-типов, например: $allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];. После загрузки файла используйте объект finfo_open(FILEINFO_MIME_TYPE) для получения реального MIME-типа и сравните его с массивом.
Пример проверки:
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $_FILES['file']['tmp_name']);
finfo_close($finfo);
if (!in_array($mimeType, $allowedTypes)) {
echo 'Файл запрещён';
}
Рекомендовано использовать именно finfo_file(), а не $_FILES['file']['type'], так как последний может быть ненадёжным при обходе через поддельные заголовки. Для повышения безопасности допустимо сочетать проверку MIME-типа с проверкой расширения, используя строгий список соответствий, например: ['jpg' => 'image/jpeg', 'png' => 'image/png', 'pdf' => 'application/pdf'].
Если MIME-тип не совпадает с ожидаемым для данного расширения, файл следует отклонить. Такая стратегия предотвращает загрузку исполняемых скриптов под видом изображений или документов.
Ограничение загрузки только безопасных файлов
Для предотвращения загрузки вредоносных файлов необходимо проверять MIME-тип и расширение файла. В PHP используйте функцию finfo_file() для получения точного типа содержимого и сравнивайте его с разрешёнными значениями, например: image/jpeg, image/png.
Ограничьте допустимые расширения через массив, например: $allowedExtensions = ['jpg','png','gif'];. Проверка должна быть независимой от имени файла, так как расширение можно подделать.
Перед сохранением файла создавайте уникальное имя и сохраняйте его вне публичной директории, чтобы исключить возможность прямого доступа через URL. Используйте функцию move_uploaded_file() только после всех проверок.
Установите лимит размера загружаемых файлов через настройки PHP: upload_max_filesize и post_max_size. Проверяйте размер на стороне сервера с помощью $_FILES['file']['size'].
Для дополнительных мер безопасности применяйте фильтрацию содержимого файлов, например проверку сигнатуры изображения, чтобы убедиться, что файл соответствует заявленному типу, а не содержит исполняемый код.
Обработка ошибок при неправильном расширении или типе файла
При загрузке файлов через PHP важно проверять не только расширение, но и MIME-тип. Для этого используют массив $_FILES и функцию mime_content_type(). Например, разрешённые расширения можно хранить в массиве $allowedExtensions = ['jpg', 'png', 'pdf'];, а допустимые MIME-типы – в $allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];.
Если расширение файла не соответствует разрешённым, следует сразу прервать обработку. Для проверки используют pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION) и сравнивают с массивом допустимых значений. В случае несоответствия возвращается конкретное сообщение, например: echo "Ошибка: недопустимое расширение файла";.
Для проверки MIME-типа проверка через $_FILES['file']['type'] ненадёжна, так как значение формируется клиентом. Надёжнее использовать mime_content_type($_FILES['file']['tmp_name']) или finfo_file(finfo_open(FILEINFO_MIME_TYPE), $_FILES['file']['tmp_name']). Несовпадение с разрешёнными типами требует остановки загрузки и логирования события для безопасности.
Обработка ошибок должна включать возврат к пользователю информативного, но безопасного сообщения. Например: echo "Файл не соответствует требованиям безопасности";. Дополнительно полезно вести лог ошибок на сервере с указанием имени файла, IP-адреса и времени попытки загрузки.
При разработке критично учитывать, что проверка расширения и MIME-типа должна быть последовательной: сначала расширение, затем MIME-тип. Это минимизирует риск загрузки вредоносных файлов и упрощает аудит безопасности.
Комбинированная проверка MIME-типа и расширения

Для повышения безопасности загрузки файлов в PHP рекомендуется одновременно проверять MIME-тип и расширение. Использование только одного метода легко обходится злоумышленниками.
Алгоритм комбинированной проверки включает несколько шагов:
- Определение MIME-типа через встроенные функции PHP:
finfo_file()сFILEINFO_MIME_TYPEдля точного определения типа содержимого.- Альтернатива:
mime_content_type(), хотяfinfo_file()считается надежнее.
- Проверка расширения файла:
- Извлечение расширения с помощью
pathinfo($filename, PATHINFO_EXTENSION). - Сравнение с заранее определённым списком допустимых расширений (например,
['jpg','png','pdf']).
- Извлечение расширения с помощью
- Сопоставление MIME-типа и расширения:
- Создать массив соответствий MIME-тип ↔ расширение.
- Проверить, соответствует ли MIME-тип заявленному расширению.
- Если несоответствие обнаружено – отклонить файл.
Пример кода проверки:
$allowedExtensions = ['jpg','png','pdf'];
$mimeMap = ['jpg' => 'image/jpeg', 'png' => 'image/png', 'pdf' => 'application/pdf'];
$ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['file']['tmp_name']);
finfo_close($finfo);
if(in_array($ext, $allowedExtensions) && isset($mimeMap[$ext]) && $mimeMap[$ext] === $mime){
// Файл допустим
}else{
// Файл отклонён
}
Рекомендации по реализации:
- Использовать строгие соответствия MIME ↔ расширение, без wildcard-типов.
- Отклонять файлы с подозрительными или отсутствующими MIME-типами.
- Не полагаться на расширение файла для безопасности – только в сочетании с MIME.
- Регулярно обновлять список допустимых MIME-типов и расширений в соответствии с требованиями приложения.
Примеры кода для загрузки файлов с проверкой типа и расширения

Ниже приведен пример PHP-кода для безопасной загрузки изображений с проверкой MIME-типа и расширения файла:
PHP:
<?php
$allowedTypes = [‘image/jpeg’, ‘image/png’, ‘image/gif’];
$allowedExtensions = [‘jpg’, ‘jpeg’, ‘png’, ‘gif’];
if (isset($_FILES[‘file’])) {
$file = $_FILES[‘file’];
$fileInfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($fileInfo, $file[‘tmp_name’]);
$extension = strtolower(pathinfo($file[‘name’], PATHINFO_EXTENSION));
if (in_array($mimeType, $allowedTypes) && in_array($extension, $allowedExtensions)) {
$uploadDir = ‘uploads/’;
$uploadPath = $uploadDir . basename($file[‘name’]);
if (move_uploaded_file($file[‘tmp_name’], $uploadPath)) {
echo «Файл загружен успешно.»;
} else {
echo «Ошибка при загрузке файла.»;
}
} else {
echo «Недопустимый тип файла или расширение.»;
}
}
?>
Для дополнительной безопасности можно использовать таблицу допустимых MIME-типов и расширений:
| MIME-тип | Расширение |
|---|---|
| image/jpeg | jpg, jpeg |
| image/png | png |
| image/gif | gif |
Пример проверки PDF-файлов:
<?php
$allowedTypes = [‘application/pdf’];
$allowedExtensions = [‘pdf’];
if (isset($_FILES[‘file’])) {
$file = $_FILES[‘file’];
$mimeType = mime_content_type($file[‘tmp_name’]);
$extension = strtolower(pathinfo($file[‘name’], PATHINFO_EXTENSION));
if (in_array($mimeType, $allowedTypes) && in_array($extension, $allowedExtensions)) {
move_uploaded_file($file[‘tmp_name’], ‘uploads/’ . $file[‘name’]);
echo «PDF загружен.»;
} else {
echo «Файл не соответствует требованиям.»;
}
}
?>
Рекомендации:
- Всегда проверяйте MIME-тип через
finfo_fileилиmime_content_type, а не только расширение. - Используйте уникальные имена файлов при сохранении, чтобы избежать перезаписи.
- Ограничивайте размер загружаемых файлов через
$_FILES['file']['size']. - Создавайте отдельную директорию для загрузок с ограниченными правами доступа.
Вопрос-ответ:
Как определить MIME-тип файла в PHP?
В PHP для определения MIME-типа можно использовать функцию mime_content_type(). Она возвращает строку с типом содержимого файла, например, «image/jpeg» или «text/plain». Пример использования: $type = mime_content_type('example.jpg');. Это позволяет проверить соответствие файла ожидаемому типу перед его обработкой или загрузкой на сервер.
Чем проверка расширения файла отличается от проверки его типа?
Проверка расширения файла анализирует только название файла и символы после точки, например, «.php» или «.jpg». Проверка типа файла через MIME-тип анализирует фактическое содержимое файла, а не только его имя. Расширение можно легко подделать, поэтому для безопасности важно использовать проверку типа файла.
Какие функции PHP лучше использовать для проверки загруженных файлов?
Для проверки загруженных файлов обычно применяют комбинацию функций: pathinfo() для извлечения расширения и mime_content_type() для проверки типа. Также полезна проверка через finfo_file() с объектом finfo_open(FILEINFO_MIME_TYPE), которая точнее определяет MIME-тип. Такой подход снижает риск загрузки нежелательных файлов на сервер.
Можно ли полностью полагаться на расширение файла для безопасности?
Нет, расширение файла не гарантирует безопасности, так как пользователь может изменить его вручную. Например, файл с кодом PHP можно переименовать в «.jpg». Поэтому для защиты сервера нужно проверять реальный MIME-тип, размер файла и содержимое при необходимости.
Как правильно реализовать проверку PHP-файлов перед загрузкой на сервер?
Сначала извлекают расширение с помощью pathinfo(), проверяя, соответствует ли оно списку разрешенных. Затем используют finfo_file() или mime_content_type(), чтобы убедиться, что MIME-тип совпадает с ожидаемым (например, «text/x-php»). Дополнительно можно ограничивать размер файла и проверять его содержимое на запрещенные конструкции, чтобы снизить риск выполнения вредоносного кода.
Как определить реальный тип файла PHP на сервере?
Для проверки типа загруженного файла в PHP обычно используют функцию finfo_file() или объект finfo. Она анализирует содержимое файла, а не только расширение, и возвращает MIME-тип. Например, для файла $file можно сделать так: $finfo = finfo_open(FILEINFO_MIME_TYPE); $type = finfo_file($finfo, $file['tmp_name']); finfo_close($finfo);. Это помогает убедиться, что файл соответствует ожидаемому типу, например image/jpeg для JPEG.
Можно ли проверять только расширение файла при загрузке?
Проверка расширения $_FILES['name'] не гарантирует безопасность, так как пользователь может изменить имя файла. Лучше использовать проверку MIME-типа через finfo_file() или mime_content_type(), а расширение использовать лишь для удобства при сохранении. Также стоит сравнивать расширение и MIME-тип вместе, чтобы исключить загрузку поддельных файлов.
