Извлечение имени файла и пути в PHP: полное учебное пособие

Раздел: Основы PHP -> Работа с именами и путями

Работа с именами и путями в PHP: извлечение имени файла и пути

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

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

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

<?php
$path = '/var/www/html/index.php';
$info = pathinfo($path);
print_r($info);
?>

имя php (имя в php)

Array
(
    [dirname] => /var/www/html
    [basename] => index.php
    [extension] => php
    [filename] => index
)

При необходимости можно получить только одно значение, передав вторым аргументом константу: PATHINFO_DIRNAME, PATHINFO_BASENAME, PATHINFO_EXTENSION, PATHINFO_FILENAME.

Как получить только имя файла без пути? (basename)

Функция basename() возвращает последний компонент пути - имя файла (или папки). Если файл имеет расширение, оно включается в результат. Для удаления расширения можно передать второй параметр.

<?php
$path = '/images/photo.jpg';
echo basename($path); // photo.jpg
echo basename($path, '.jpg'); // photo
?>

Возможная проблема:

На Windows basename() обрабатывает как прямой (/) так и обратный слеш (\), но на Linux только прямой слеш. Если путь приходит из внешнего источника, стоит привести разделители к одному виду.

Как получить директорию, содержащую файл? (dirname)

Функция dirname() возвращает родительскую директорию указанного пути. Если путь не содержит слешей, возвращает точку (.).

<?php
echo dirname('/etc/nginx/nginx.conf'); // /etc/nginx
echo dirname('file.txt'); // .
?>

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

С помощью pathinfo($path, PATHINFO_EXTENSION) или substr(strrchr($path, '.'), 1). Первый способ предпочтительнее, так как он учитывает пустые расширения и точки в имени.

<?php
$path = 'archive.tar.gz';
echo pathinfo($path, PATHINFO_EXTENSION); // gz (заметно: вернёт только последнее расширение)
echo end(explode('.', $path)); // gz (но сломается, если нет точки)
?>

Типичная ошибка:

Использование explode() или strrchr() для пути с точками в директории (например, /path.to/file.txt) приведёт к неверному результату. pathinfo() корректно обрабатывает такие случаи.

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

Используйте pathinfo($path, PATHINFO_FILENAME). Это самый надёжный способ.

<?php
$path = 'document.pdf';
echo pathinfo($path, PATHINFO_FILENAME); // document
$path2 = '/var/log/error.log';
echo pathinfo($path2, PATHINFO_FILENAME); // error
?>

Как узнать абсолютный путь к текущему файлу? (__FILE__, __DIR__)

Магические константы __FILE__ и __DIR__ содержат полный путь и директорию текущего скрипта. __DIR__ эквивалентно dirname(__FILE__).

<?php
echo __FILE__; // /var/www/html/index.php
echo __DIR__; // /var/www/html
?>

Как преобразовать относительный путь в абсолютный? (realpath)

realpath() возвращает канонизированный абсолютный путь, разрешая символические ссылки и удаляя лишние элементы (например, ..). Если путь не существует, возвращает false.

<?php
$relative = './../images/photo.jpg';
echo realpath($relative); // /var/www/images/photo.jpg (зависит от системы)
?>

Возможная проблема:

Если целевой файл или директория не существуют, realpath() вернёт false. Для несуществующих путей используйте realpath(dirname($path)) . '/' . basename($path).

Расширенные примеры работы с именами и путями в PHP

1. Извлечение имени файла из URL (строки, похожей на путь)

Функции basename и pathinfo работают и с URL, если передать их как строку. Однако для сложных URL (с параметрами) сначала нужно выделить путь.

Пример
<?php
$url = 'https://example.com/img/photo.jpg?w=800';
$path = parse_url($url, PHP_URL_PATH);
echo basename($path); // photo.jpg
echo pathinfo($path, PATHINFO_FILENAME); // photo
?>
photo.jpg
photo

2. Обработка множественных расширений (например, .tar.gz)

pathinfo() возвращает только последнее расширение. Если нужно получить все части после первой точки, используйте explode или регулярное выражение.

Пример
<?php
$file = 'backup.tar.gz';
$parts = explode('.', $file);
$extensions = array_slice($parts, 1); // ['tar', 'gz']
echo implode('.', $extensions); // tar.gz
$name = $parts[0]; // backup
?>
tar.gz
backup

3. Получение списка файлов в директории с их именами без расширения

Пример
<?php
$dir = '/path/to/files';
$files = scandir($dir);
foreach ($files as $file) {
    if (is_file($dir . '/' . $file)) {
        $name = pathinfo($file, PATHINFO_FILENAME);
        echo $name . PHP_EOL;
    }
}
?>
document
image
report

4. Безопасное построение пути с помощью DIRECTORY_SEPARATOR

Пример
<?php
$base = '/var/www';
$folder = 'uploads';
$file = 'file.txt';
$fullPath = $base . DIRECTORY_SEPARATOR . $folder . DIRECTORY_SEPARATOR . $file;
echo $fullPath; // /var/www/uploads/file.txt
// Для кросс-платформенности используйте DIRECTORY_SEPARATOR
?>
/var/www/uploads/file.txt

5. Извлечение родительской директории несколько уровней вверх

Комбинируйте dirname() несколько раз или используйте realpath.

Пример
<?php
$path = '/a/b/c/d/file.txt';
$parent = dirname(dirname($path)); // '/a/b/c'
// Или через realpath:
$parent2 = realpath($path . '/../..'); // разрешит символические ссылки
?>
/a/b/c

6. Получение имени файла без расширения из строки с путём (без pathinfo)

Пример
<?php
$path = '/var/log/app.log';
$basename = basename($path); // app.log
$dotPos = strrpos($basename, '.');
$filename = ($dotPos !== false) ? substr($basename, 0, $dotPos) : $basename;
echo $filename; // app
?>
app

Проблема: не учтены случаи без расширения или имя начинается с точки (скрытые файлы).

Для скрытых файлов (например, .htaccess) strrpos вернёт 0, и substr даст пустую строку. Лучше использовать pathinfo, который возвращает filename как .htaccess.

7. Проверка существования файла и извлечение его имени

Пример
<?php
$path = '/etc/passwd';
if (file_exists($path)) {
    $info = pathinfo($path);
    echo 'Имя: ' . $info['filename'] . ', расширение: ' . $info['extension'];
} else {
    echo 'Файл не найден';
}
?>
Имя: passwd, расширение: 

Имя в PHP - comments

En
имя php (php)