Avatar ·

Как получить расширение файла в PHP? (подробное руководство)

Всем привет! Я новичок в PHP и никак не могу разобраться с такой, казалось бы, простой задачей: как правильно получить расширение файла из его имени? У меня есть переменная, содержащая путь к файлу, например: ```php $filename = "images/myphoto.jpg"; ``` Мне нужно извлечь только расширение — в данном случае "jpg". Я попробовал несколько способов, но все они работают неправильно в разных ситуациях. Например, я использовал explode: ```php $parts = explode('.', $filename); $ext = end($parts); ``` Но если в имени файла есть несколько точек, например "my.file.name.jpg", то этот способ выдаст "jpg". Это вроде работает, но есть ли более надёжный метод? А что если у файла вообще нет расширения? Или если это системный файл вроде ".htaccess"? Или если путь содержит папки с точками, например "/var/www/site.com/uploads/archive.tar.gz"? Я погуглил и нашёл функцию pathinfo(), но не совсем понял, как её правильно использовать. Она возвращает массив, и там есть элемент 'extension'. Но работает ли она корректно со всеми типами путей? Что насчёт безопасности? Может быть, есть ещё какие-то подводные камни? Буду благодарен за подробное объяснение с примерами кода для разных случаев. Заранее спасибо! <<>>

Правильное решение: функция pathinfo()

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

<?php
$filename = "images/myphoto.jpg";
$info = pathinfo($filename);
echo $info['extension']; // Выведет: jpg
?>

Почему это лучший вариант?

  • Универсальность: работает с абсолютными и относительными путями
  • Безопасность: корректно обрабатывает файлы без расширения и скрытые файлы (например, .htaccess)
  • Производительность: функция оптимизирована и работает быстрее самодельных решений
  • Предсказуемость: возвращает пустую строку, если расширения нет (вместо ошибки)

Примеры для разных ситуаций

1. Файл с несколькими точками:

<?php
$filename = "archive.tar.gz";
$ext = pathinfo($filename, PATHINFO_EXTENSION);
echo $ext; // Выведет: gz (последнее расширение)
?>

2. Файл без расширения:

<?php
$filename = "README";
$ext = pathinfo($filename, PATHINFO_EXTENSION);
echo $ext; // Выведет: пустую строку (не null и не false)
var_dump($ext); // string(0) ""
?>

3. Скрытый файл (Unix):

<?php
$filename = ".htaccess";
$ext = pathinfo($filename, PATHINFO_EXTENSION);
echo $ext; // Выведет: htaccess
?>

4. Путь с папками, содержащими точки:

<?php
$filename = "/var/www/site.com/uploads/document.pdf";
$ext = pathinfo($filename, PATHINFO_EXTENSION);
echo $ext; // Выведет: pdf (папки игнорируются)
?>

Дополнительные возможности pathinfo()

Функция может возвращать не только расширение, но и другие части пути. Используйте второй параметр для получения конкретного элемента:

<?php
$filename = "/var/www/uploads/photo.jpg";

// Получить всё, кроме расширения
echo pathinfo($filename, PATHINFO_FILENAME); // photo

// Получить имя файла с расширением
echo pathinfo($filename, PATHINFO_BASENAME); // photo.jpg

// Получить директорию
echo pathinfo($filename, PATHINFO_DIRNAME); // /var/www/uploads
?>

Важные замечания

  • Кодировка: pathinfo() корректно работает с UTF-8 именами файлов
  • Регистр: расширение возвращается в том же регистре, что и в имени файла. Если нужно привести к нижнему регистру, используйте strtolower()
  • Проверка существования: pathinfo() не проверяет, существует ли файл на диске — она просто разбирает строку
  • Безопасность: никогда не используйте расширение файла как единственный критерий безопасности (например, для проверки загружаемых изображений), так как его легко подделать

Когда НЕ использовать pathinfo()

Если вам нужно получить MIME-тип файла (например, image/jpeg), а не расширение, используйте mime_content_type() или finfo_file(). Расширение — это просто текст в имени, а MIME-тип определяется по содержимому файла.

<<>>

Альтернативный подход: использование strrpos() и substr()

Если по каким-то причинам вы не можете использовать pathinfo() (например, в очень старых версиях PHP), можно реализовать получение расширения вручную:

<?php
function getFileExtension($filename) {
    $pos = strrpos($filename, '.');
    if ($pos === false) {
        return ''; // Нет расширения
    }
    return substr($filename, $pos + 1);
}

echo getFileExtension("image.jpg"); // jpg
echo getFileExtension("archive.tar.gz"); // gz
echo getFileExtension("noext"); // (пустая строка)
?>

Как это работает:

  • strrpos() находит позицию последней точки в строке
  • Если точка не найдена (файл без расширения), возвращаем пустую строку
  • substr() извлекает всё, что находится после последней точки

Преимущества: полный контроль над логикой, не зависит от локали или версии PHP.

Недостатки: не обрабатывает некоторые крайние случаи (например, пути с точками в названиях папок — в отличие от pathinfo(), которая делает это корректно). Для большинства простых сценариев этого достаточно.