Методы получения имени файла из пути в PHP: обзор и практика

Раздел: Работа с файлами -> Работа с файлами

Основные способы извлечения имени файла

Наиболее простой и эффективный способ получения имени файла из полного пути - функция basename(). Она возвращает последний компонент пути (имя файла) и опционально может удалить указанное расширение.


<?php
$path = '/var/www/html/images/photo.jpg';
$filename = basename($path);
echo $filename; // photo.jpg
?>
photo.jpg

Для извлечения имени без расширения второй параметр:


$nameWithoutExt = basename($path, '.jpg');
echo $nameWithoutExt; // photo
photo

Случаи использования: обработка путей из файловой системы, логирование, загрузка файлов (из $_FILES['file']['name']), извлечение имени из URL.

Проблемы и ошибки

  • Передача пустой строки или null приводит к ошибке (PHP 8+ генерирует TypeError). Используйте проверку is_string().
  • Если путь заканчивается слешем, basename может вернуть пустую строку или предыдущий компонент (зависит от системы). Всегда проверяйте результат.
  • Функция не проверяет существование файла, она просто парсит строку.

Как получить имя файла и расширение по отдельности с помощью pathinfo?

Функция pathinfo() возвращает ассоциативный массив с ключами dirname, basename, extension (если есть) и filename (имя без расширения). Можно указать одну константу для получения конкретного элемента.


$info = pathinfo('/home/user/docs/report.txt');
echo $info['filename']; // report
echo $info['extension']; // txt
report
txt

Постоянная PATHINFO_FILENAME и PATHINFO_EXTENSION:


$filename = pathinfo('/path/file.doc', PATHINFO_FILENAME);
echo $filename; // file

Возможные сложности

  • Для файлов без расширения ключ extension будет отсутствовать или вернет пустую строку.
  • Если путь содержит строку с точкой в имени каталога, pathinfo может некорректно выделить расширение. Например, '/path.to/file' - расширением может быть '.to/file'? На самом деле pathinfo корректно обрабатывает, но для абсолютной надежности лучше использовать basename в комбинации с explode('.').

Как использовать explode для извлечения имени файла?

Путь можно разделить по DIRECTORY_SEPARATOR (или слешу) и взять последний элемент массива.


$parts = explode('/', '/var/www/html/index.php');
$filename = end($parts);
echo $filename; // index.php
index.php

Для получения имени без расширения добавьте ещё explode по точке.


$parts = explode('/', $path);
$nameWithExt = end($parts);
$nameParts = explode('.', $nameWithExt);
$name = $nameParts[0]; // имя без расширения
echo $name;

Недостатки

  • Не учитывается различие слешей в Windows/Unix. DIRECTORY_SEPARATOR может быть обратным слешем. Лучше использовать basename.
  • Если в имени файла есть точки, explode('.') разобьет неправильно (например, 'archive.tar.gz' - получим 'archive'). Используйте pathinfo или preg_match.

Как извлечь имя файла из URL?

Сначала извлеките путь из URL с помощью parse_url(), затем примените basename.


$url = 'https://example.com/images/photo.jpg?size=large';
$path = parse_url($url, PHP_URL_PATH);
$filename = basename($path);
echo $filename; // photo.jpg
photo.jpg

Также можно удалить GET-параметры и якоря.

Проблемы

  • URL может быть закодирован (например, %20). Для читаемого имени декодируйте с помощью urldecode() после basename.
  • Некоторые URL содержат вложенные пути без имени файла (как '/' ). basename вернет пустую строку.

Как получить имена файлов из массива $_FILES?

При загрузке файла через форму изначальное имя хранится в $_FILES['field']['name']. Не доверяйте этому значению из-за возможной инъекции, но для вывода или логирования можно использовать.


$originalName = $_FILES['avatar']['name'];
$cleanName = basename($originalName);
echo $cleanName;

Используйте basename для фильтрации потенциальных путей (например, если злоумышленник передаст '../../etc/passwd').

Расширенные примеры извлечения имени файла

Извлечение имени из пути с произвольным разделителем

На Windows разделитель обратный слеш. Функция basename работает и с ним, но для надёжности можно использовать DIRECTORY_SEPARATOR.

Пример

$winPath = 'C:/Users/Doc/file.txt';
// Используем DIRECTORY_SEPARATOR
$parts = explode(DIRECTORY_SEPARATOR, $winPath);
$filename = end($parts);
echo $filename; // file.txt
// Также можно basename, он поддерживает оба вида слешей.
echo basename($winPath); // file.txt
file.txt
file.txt

Получение имени без расширения для файлов с множественными точками

Для 'archive.tar.gz' pathinfo вернет extension = 'gz', filename = 'archive.tar'. Если нужно 'archive', используйте basename и удалите последнее расширение вручную.

Пример

$file = 'backup.tar.gz';
$base = basename($file); // backup.tar.gz
$dotPos = strrpos($base, '.');
if ($dotPos !== false) {
    $nameWithoutExt = substr($base, 0, $dotPos);
} else {
    $nameWithoutExt = $base;
}
echo $nameWithoutExt; // backup.tar
backup.tar

Обработка закодированных URL

Пример

$url = 'https://example.com/%D1%84%D0%BE%D1%82%D0%BE.jpg';
$path = parse_url($url, PHP_URL_PATH);
$filename = basename($path);
$decoded = urldecode($filename);
echo $decoded; // фото.jpg
фото.jpg

Использование DirectoryIterator для получения имён файлов в папке

Пример

$dir = '/var/www/html/uploads';
$iterator = new DirectoryIterator($dir);
$files = [];
foreach ($iterator as $fileinfo) {
    if ($fileinfo->isFile()) {
        $files[] = $fileinfo->getFilename(); // только имя файла
    }
}
print_r($files);
Array ( [0] => image1.jpg [1] => document.pdf [2] => readme.txt )

Извлечение имени файла из пути с удалением GET-параметров

Пример

$url = 'http://example.com/download.php?file=report.pdf';
$path = parse_url($url, PHP_URL_PATH); // /download.php
$filename = basename($path);
// GET-параметры не попали в путь, поэтому безопасно.
echo $filename; // download.php
download.php

Получение последнего компонента пути с помощью array_slice и DIRECTORY_SEPARATOR

Пример

$path = '/home/user/projects/script.php';
$parts = explode('/', $path);
$filename = array_slice($parts, -1)[0];
echo $filename; // script.php
script.php

Получение имени файла в PHP - comments

En
Files php name (php)