Avatar ·

Как получить расширение файла в PHP? Надёжные способы и подводные камни

Всем привет! Я только начал изучать PHP и пишу небольшой скрипт для загрузки изображений на сервер. Мне нужно проверять расширение загружаемого файла, чтобы, например, разрешить только JPG и PNG. Я пробовал использовать функцию `explode()` и брать последний элемент массива, но это кажется костылём. Вот мой код: ```php $filename = 'myphoto.jpg'; $parts = explode('.', $filename); $extension = end($parts); echo $extension; // jpg ``` Но что будет, если имя файла содержит несколько точек, например `my.file.name.jpg`? Или если у файла вообще нет расширения? Я слышал, что есть специальные функции для этого. Подскажите, пожалуйста, как правильно и безопасно получить расширение файла в PHP? Какие есть встроенные функции и что лучше использовать в разных ситуациях? Заранее спасибо за помощь! <<>>

Основное решение: функция pathinfo()

Самый правильный и универсальный способ получить расширение файла в PHP — использовать встроенную функцию pathinfo(). Она специально предназначена для разбора пути к файлу и возвращает массив с различными компонентами: директория, имя файла, расширение и имя без расширения.

<?php
$filename = 'my.file.name.jpg';
$info = pathinfo($filename);
$extension = $info['extension']; // 'jpg'

// Или ещё короче:
$extension = pathinfo($filename, PATHINFO_EXTENSION);
echo $extension; // jpg
?>

Функция pathinfo() корректно обрабатывает файлы с несколькими точками, файлы без расширения и даже полные пути:

<?php
// Файл с несколькими точками
echo pathinfo('archive.tar.gz', PATHINFO_EXTENSION); // 'gz'

// Файл без расширения
echo pathinfo('README', PATHINFO_EXTENSION); // '' (пустая строка)

// Полный путь
echo pathinfo('/var/www/uploads/photo.jpg', PATHINFO_EXTENSION); // 'jpg'
?>

Дополнительные способы

Иногда может потребоваться альтернативный подход. Вот ещё два распространённых метода:

  • Функция substr() + strrpos() — ручной разбор строки:
<?php
$filename = 'document.pdf';
$extension = substr($filename, strrpos($filename, '.') + 1);
echo $extension; // pdf
?>

Этот метод находит последнюю точку в строке и берёт всё после неё. Он надёжнее простого explode(), так как учитывает множественные точки.

  • Функция strrchr() — находит последнее вхождение символа:
<?php
$filename = 'image.jpeg';
$extension = substr(strrchr($filename, '.'), 1);
echo $extension; // jpeg
?>

Важные замечания для начинающих

Помните, что расширение файла — это всего лишь часть имени, и его легко подделать. Злоумышленник может загрузить PHP-скрипт под видом image.jpg.php. Для реальной проверки типа файла используйте mime_content_type() или проверку содержимого (например, через finfo).

Также учитывайте регистр: расширение может быть JPG, jpg или Jpg. Для сравнения всегда приводите к нижнему регистру:

<?php
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (in_array($ext, ['jpg', 'jpeg', 'png'])) {
    echo 'Разрешённый формат';
}
?>

Итог: используйте pathinfo() — это самый чистый, надёжный и читаемый способ. Остальные методы применяйте только если вам нужен специфический контроль над процессом разбора.

<<>>

Альтернативный подход: регулярные выражения

Если вам нужно извлечь расширение в сложных условиях (например, из URL с параметрами или из строки с нестандартными символами), можно использовать регулярные выражения:

<?php
$filename = 'file.name.with.dots.txt';
preg_match('/\.([a-zA-Z0-9]+)$/', $filename, $matches);
$extension = $matches[1] ?? '';
echo $extension; // txt
?>

Этот метод ищет точку, за которой следуют буквы и цифры в конце строки. Он даёт больше контроля над тем, что считать расширением. Например, можно ограничить длину расширения или разрешить только определённые символы.

Работа с загруженными файлами

Для файлов, загруженных через форму, получайте расширение из оригинального имени:

<?php
if ($_FILES['file']['error'] === UPLOAD_ERR_OK) {
    $ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
    // Дальнейшая обработка...
}
?>

Важно: никогда не доверяйте только расширению для безопасности. Всегда проверяйте MIME-тип и содержимое файла. Расширение — это лишь подсказка, а не гарантия.