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

Раздел: PHP -> Файловые функции

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

Работа с именами файлов часто требуется при логировании, создании самоссылающихся ссылок или обработке загруженных данных. Рассмотрим различные подходы к извлечению имени файла из пути, включая наиболее эффективное решение и альтернативные варианты.

Наиболее универсальный способ получения имени текущего исполняемого PHP-файла — использовать константу __FILE__ вместе с функцией basename():

<?php
$filename = basename(__FILE__);
echo $filename; // index.php
?>

Index php filename (имя файла в php)

Этот метод возвращает имя файла с расширением, независимо от того, включён ли файл через include или выполняется напрямую. Важно: __FILE__ всегда содержит полный путь к файлу, в котором она написана, поэтому basename корректно извлекает последний компонент.

Цель: получение имени текущего скрипта для логирования, самодиагностики или формирования ссылок.

Проблема: если файл включён через include из другой директории, __FILE__ покажет путь к включённому файлу, а не к основному скрипту. Решение: использовать $_SERVER['SCRIPT_FILENAME'] для получения пути к основному скрипту.

Как получить имя файла из произвольного пути?

Функция basename() принимает строку пути и возвращает имя файла (последний компонент).

<?php
$path = '/var/www/html/project/index.php';
$filename = basename($path);
echo $filename; // index.php
?>

Это полезно при обработке списка файлов, полученных из glob() или scandir().

Проблема: basename() чувствительна к локали. Если путь содержит многобайтовые символы (например, кириллица), результат может быть обрезан. Решение: установить локаль setlocale(LC_CTYPE, 'UTF-8').

Как получить имя файла без расширения?

Функция pathinfo() с константой PATHINFO_FILENAME извлекает только имя без расширения.

<?php
$path = 'document.txt';
$name = pathinfo($path, PATHINFO_FILENAME);
echo $name; // document
?>

Это удобно для создания временных файлов или проверки базового имени.

Проблема: если в имени файла несколько точек (например, file.tar.gz), PATHINFO_FILENAME вернёт только 'file.tar'. Решение: использовать explode() с проверкой последнего сегмента.

Как получить только расширение файла?

С помощью pathinfo() и PATHINFO_EXTENSION можно извлечь расширение.

<?php
$path = 'image.jpg';
$ext = pathinfo($path, PATHINFO_EXTENSION);
echo $ext; // jpg
?>

Применяется для фильтрации типов файлов при загрузке.

Проблема: расширение может отсутствовать. В таком случае возвращается пустая строка. Решение: проверять результат и обрабатывать как отдельный случай.

Как получить имя скрипта, вызванного через URL?

Суперглобальные переменные $_SERVER['SCRIPT_NAME'] или $_SERVER['PHP_SELF'] содержат путь от корня веб-сервера до текущего скрипта. basename() выделяет имя.

<?php
$script = basename($_SERVER['SCRIPT_NAME']);
echo $script; // index.php
?>

Подходит для создания форм с действием на себя или ссылок на текущую страницу.

Проблема: $_SERVER['PHP_SELF'] уязвим к XSS, если URL содержит манипуляции. Решение: использовать $_SERVER['SCRIPT_NAME'] или фильтровать через htmlspecialchars().

Как получить имя файла из полного пути с нормализацией?

Функция realpath() преобразует путь в канонический абсолютный путь, после чего можно применить basename().

<?php
$relative = './../test/../folder/file.php';
$normalized = realpath($relative);
$filename = basename($normalized);
echo $filename; // file.php
?>

Помогает избежать ошибок, связанных с символическими ссылками или относительными путями.

Проблема: realpath() возвращает false, если файл не существует. Решение: проверять результат перед использованием.

Как извлечь имя файла из URL (не локального пути)?

Для URL можно использовать parse_url() и затем basename().

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

Применяется при парсинге внешних ресурсов.

Расширенные примеры работы с именем файла

Извлечение имени без расширения для файлов с несколькими точками

Файлы типа archive.tar.gz требуют особого подхода, так как стандартное расширение — последняя часть после последней точки. Чтобы получить имя до первого расширения, можно использовать strpos().

Пример
<?php
$filename = 'backup.tar.gz';
$dotPos = strpos($filename, '.');
$base = ($dotPos === false) ? $filename : substr($filename, 0, $dotPos);
echo $base; // backup
?>
Output: backup

Для получения только последнего расширения удобнее pathinfo():

Пример
<?php
$ext = pathinfo('backup.tar.gz', PATHINFO_EXTENSION);
echo $ext; // gz
?>
Output: gz

Объектно-ориентированное получение имени файла через SplFileInfo

Класс SplFileInfo предоставляет методы getBasename(), getFilename(), getExtension() и getPath().

Пример
<?php
$file = new SplFileInfo('/var/www/html/app/config.php');
echo $file->getBasename();      // config.php
echo $file->getFilename();     // config.php
echo $file->getExtension();    // php
echo $file->getPath();         // /var/www/html/app
?>
config.php
config.php
php
/var/www/html/app

Этот подход удобен в ООП-стиле, особенно при работе с итераторами.

Получение имен всех файлов в директории с помощью DirectoryIterator

Использование итератора позволяет получить имена файлов без расширений.

Пример
<?php
$dir = new DirectoryIterator('./uploads');
foreach ($dir as $fileInfo) {
    if ($fileInfo->isFile()) {
        echo $fileInfo->getBasename('.txt') . PHP_EOL;
    }
}
?>
file1
file2
notes

Метод getBasename($suffix) отсекает указанное расширение.

Обработка путей с разными разделителями (Windows vs Unix)

Константа DIRECTORY_SEPARATOR помогает писать кросс-платформенный код. Можно использовать basename(), который корректно работает с обоими разделителями.

Пример
<?php
$winPath = 'C:\\Users\\Admin\\file.php';
$unixPath = '/home/user/file.php';
echo basename($winPath);  // file.php
echo basename($unixPath); // file.php
?>
file.php
file.php

Извлечение имени файла из пользовательского ввода с безопасной фильтрацией

При обработке загрузок нельзя доверять имени файла напрямую. Лучше извлечь безопасное имя через basename() и удалить недопустимые символы.

Пример
<?php
$userInput = '../../../etc/passwd';
$safe = basename($userInput);
$safe = preg_replace('/[^a-zA-Z0-9._-]/', '_', $safe);
echo $safe; // passwd
// Примечание: имя 'passwd' без расширения, так как исходное имя не содержало расширения
?>
passwd

Такая фильтрация предотвращает Path Traversal атаки.

Сравнение производительности basename vs explode

Для больших массивов путей basename() обычно быстрее, но можно использовать explode() с последним элементом.

Пример
<?php
$paths = ['/a/b/c.php', '/d/e/f.html', '/g/h/i.txt'];
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    foreach ($paths as $p) {
        $b = basename($p);
    }
}
echo 'basename: ' . (microtime(true) - $start) . " s\n";
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    foreach ($paths as $p) {
        $parts = explode('/', $p);
        $b = end($parts);
    }
}
echo 'explode: ' . (microtime(true) - $start) . " s\n";
?>
basename: 0.015 s
explode: 0.022 s

Результаты могут варьироваться, но basename() оптимизирована на уровне C.

Имя файла в PHP - comments

En
Index php filename (php)