Как узнать путь и имя выполняемого PHP скрипта
Основы работы с текущим файлом в PHP
При разработке на PHP часто требуется узнать полный путь или имя файла, который выполняется в данный момент. Это необходимо для логирования, подключения ресурсов, вычисления относительных путей или отладки. Ниже рассматриваются основные способы получения этих данных, их особенности и типичные ошибки.
Как получить полный путь и имя текущего PHP скрипта?
Наиболее надёжное и универсальное решение - использовать предопределённую константу __FILE__. Она всегда содержит абсолютный путь к файлу, в котором она была вызвана, включая имя файла.
<?php
echo __FILE__;
// Результат: /var/www/html/index.php (или другой путь)
?>
Php текущий файл (получение текущего файла php (путь, имя))
Для получения только имени файла применяется функция basename():
<?php
echo basename(__FILE__);
// Результат: index.php
?>
Для получения директории без имени файла - функция dirname() или константа __DIR__ (доступна с PHP 5.3):
<?php
echo dirname(__FILE__); // или __DIR__
// Результат: /var/www/html
?>
Проблемы и их решения:
- Если файл включён через
includeилиrequire,__FILE__всё равно указывает на текущий выполняемый файл (тот, где написана константа). Это ожидаемое поведение. - На некоторых серверах (например, при использовании символических ссылок)
__FILE__может возвращать путь через symlink. Для получения реального физического пути используйтеrealpath(__FILE__). - Не путайте
__FILE__с$argv[0](для CLI) - последний может быть относительным.
Как получить путь к скрипту из суперглобального массива $_SERVER?
В веб-окружении бывает полезен $_SERVER['SCRIPT_FILENAME']. Он содержит абсолютный путь к основному (входному) скрипту, который обрабатывает текущий запрос. Однако, если код выполняется внутри включённого файла, $_SERVER['SCRIPT_FILENAME'] всё равно вернёт путь к родительскому скрипту, а не к текущему. Поэтому для определения имени именно выполняемого файла он подходит не всегда.
<?php
// В файле /var/www/html/include.php
echo $_SERVER['SCRIPT_FILENAME'];
// Если запрос пришёл на index.php, результат: /var/www/html/index.php
?>
Ошибка: использование $_SERVER['PHP_SELF'] для получения имени файла - этот элемент содержит путь относительно корня документа, а не полный путь, и может быть подвержен XSS-атакам. Для безопасного получения имени файла используйте basename(__FILE__).
Как разобрать путь на составляющие (расширение, база, директория)?
Функция pathinfo() возвращает ассоциативный массив с частями пути:
<?php
$info = pathinfo(__FILE__);
echo $info['dirname']; // /var/www/html
echo $info['basename']; // index.php
echo $info['extension']; // php
echo $info['filename']; // index
?>
Это удобно, когда нужно отдельно использовать имя без расширения.
Важно: pathinfo() не нормализует путь, поэтому перед использованием следует применить realpath(), если требуется разрешить символические ссылки или убрать относительные элементы (например, ..).
Как получить текущий файл в консольном (CLI) скрипте?
Для CLI-скриптов __FILE__ работает так же. Дополнительно можно использовать глобальную переменную $argv[0], которая содержит имя вызываемого скрипта (часто с относительным путём). Преимущество $argv[0] - его видит только основной скрипт, даже если он подключает другие файлы. Но для абсолютного пути снова лучше __FILE__.
<?php
echo 'argv[0]: ' . $argv[0] . PHP_EOL;
echo '__FILE__: ' . __FILE__ . PHP_EOL;
// Пример вывода:
// argv[0]: script.php
// __FILE__: /home/user/script.php
?>
Расширенные примеры использования
Ниже приведены более сложные ситуации и комбинации методов получения информации о текущем файле.
Пример 1. Нормализация пути через realpath()
Если в файловой системе используются символические ссылки, __FILE__ может вернуть путь, проходящий через них. Функция realpath() возвращает канонический абсолютный путь.
<?php
// Допустим, /var/www/index.php это симлинк на /home/user/app/index.php
echo __FILE__ . PHP_EOL;
echo realpath(__FILE__) . PHP_EOL;
?>
/var/www/index.php /home/user/app/index.php
Пример 2. Определение базовой директории приложения
Часто требуется получить корневую папку проекта. Если известна структура, можно подняться на несколько уровней от __DIR__:
<?php
// Файл /var/www/html/subdir/config.php
$root = dirname(__DIR__, 2); // поднимаемся на два уровня: html, var
echo $root;
?>
/var/www
Пример 3. Проверка, является ли файл включённым или основным
Сравнение __FILE__ и $_SERVER['SCRIPT_FILENAME'] позволяет понять, выполняется ли текущий код как основной скрипт:
<?php
if (realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME'])) {
echo 'Это основной скрипт';
} else {
echo 'Файл был подключён';
}
?>
(Зависит от сценария)
Пример 4. Получение имени файла с учётом разных расширений
pathinfo() с отдельным параметром:
<?php
echo pathinfo(__FILE__, PATHINFO_FILENAME); // только имя без расширения
echo pathinfo(__FILE__, PATHINFO_EXTENSION); // расширение
?>
index php
Пример 5. Работа с относительными путями во включаемых файлах
Чтобы избежать проблем при подключении из разных мест, всегда используйте абсолютный путь через __DIR__:
<?php
// config.php в папке /var/www/html/config/
require __DIR__ . '/../vendor/autoload.php';
// вместо относительного '../vendor/autoload.php', который зависил бы от текущей рабочей директории
?>