Путь к директории выполняемого скрипта в PHP

Раздел: Программирование -> Пути

Пути к папке PHP скрипта: обзор методов

Основной и наиболее надёжный способ

Для получения абсолютного пути к папке текущего PHP файла применяется магическая константа __DIR__. Она возвращает полный путь к директории, в которой располагается скрипт, без завершающего слеша. Этот способ гарантирует корректный результат независимо от того, какой скрипт вызвал include или require.


<?php
$scriptDir = __DIR__;
echo $scriptDir;
?>
  

Php папка скрипта (папка php скрипта)

Результат (пример для Linux):

/var/www/html/project/app

Типичная ошибка и её решение

Если скрипт включён из другого файла (например, через include), __DIR__ всё равно указывает на папку того файла, где константа записана. Новички иногда путают её с текущей рабочей директорией. Для получения директории включающего файла следует использовать переменную $_SERVER['SCRIPT_FILENAME'] или конструкцию dirname($_SERVER['SCRIPT_FILENAME']).

Как получить путь к папке самого скрипта, если он подключён через include?


<?php
// Файл, который делают include
$includedDir = __DIR__; // директория этого файла
$callerDir = dirname($_SERVER['SCRIPT_FILENAME']); // директория главного скрипта
?>
  

Вариант 1: dirname(__FILE__)

До появления __DIR__ (PHP 5.3) использовали dirname(__FILE__). Результат идентичен, но код становится более громоздким. В современных проектах рекомендуется __DIR__.


<?php
$dirFromFile = dirname(__FILE__);
echo $dirFromFile;
?>
  

Ошибка: если файл передан через символическую ссылку, __FILE__ вернёт реальный путь, а __DIR__ тоже. Для работы с ссылками нужен realpath().

Вариант 2: realpath() для разрешения симлинков

Когда необходимо получить физический путь без символических ссылок, используется функция realpath(). Она принимает путь и возвращает канонический абсолютный путь.


<?php
$physicalDir = realpath(__DIR__);
echo $physicalDir;
?>
  

Если текущая папка ведёт на другую директорию через симлинк, результат будет отличаться.

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


<?php
$dir = realpath(__DIR__ . '/nonexistent');
if ($dir === false) {
    echo 'Путь не найден';
}
?>
    

Вариант 3: getcwd() - текущая рабочая директория

Функция getcwd() возвращает директорию, в которой в данный момент выполняется скрипт (рабочий каталог). Она не связана с расположением самого файла, а зависит от того, откуда был запущен PHP (например, из CLI или из веб-сервера).


<?php
$cwd = getcwd();
echo $cwd;
?>
  

Результат может отличаться от __DIR__. Часто используется для операций с файлами, когда нужно указать путь относительно рабочего каталога.

Ошибка: при смене рабочего каталога через chdir() значение getcwd() изменится, что может привести к неожиданным последствиям. Рекомендуется всегда использовать абсолютные пути на основе __DIR__.

Вариант 4: $_SERVER['DOCUMENT_ROOT'] - корень веб-сервера

Для веб-приложений часто требуется путь к документ-руту (DocumentRoot). Эта информация хранится в суперглобальной переменной $_SERVER['DOCUMENT_ROOT']. Однако она не всегда доступна (например, в CLI) и зависит от конфигурации сервера.


<?php
$docRoot = $_SERVER['DOCUMENT_ROOT'] ?? '/var/www/html';
echo $docRoot;
?>
  

Проблема: переменная может отсутствовать или содержать путь с завершающим слешем в разных ОС. Также при переопределении DocumentRoot через .htaccess или конфигурацию виртуального хоста значение может не совпадать с реальным расположением скрипта.

Вариант 5: Комбинирование с dirname() для подъёма по дереву

Для получения родительской директории используется dirname(__DIR__). Это пригодится, когда нужен путь к корню проекта или к общей папке.


<?php
$projectRoot = dirname(__DIR__, 2); // подняться на два уровня вверх
echo $projectRoot;
?>
  

Функция dirname() принимает необязательный второй аргумент (с PHP 7.0), указывающий количество уровней вверх.

Ошибка: если количество уровней превышает глубину папки, dirname() продолжит подниматься до корня файловой системы (например, /). Это может привести к неожиданным результатам. Следует проверять, что полученный путь не равен корневому.

Расширенные примеры использования путей к папке скрипта

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

Часто в проектах требуется знать абсолютный путь к корневой директории независимо от того, где находится вызывающий скрипт. Определение корня через относительные пути может быть ненадёжным. Ниже представлен способ на основе __DIR__ и конфигурационного файла.

Пример

<?php
// Файл config.php в корне проекта
define('ROOT_PATH', __DIR__);
?>

// В любом другом файле
require_once __DIR__ . '/config.php';
echo ROOT_PATH;
?>
/var/www/html/project

Пояснение: константа ROOT_PATH определяется в файле, расположенном в корне. Все остальные скрипты подключают этот файл и используют константу. Такой подход исключает дублирование кода и упрощает поддержку.

Проблема: если файл config.php переместить, все ссылки сломаются. Рекомендуется хранить его в фиксированном месте и использовать __DIR__ в момент определения константы.

Пример 2: Автозагрузка классов PSR-4 с динамическим определением путей

В современных PHP проектах автозагрузка классов обычно настраивается через Composer. Но вручную можно реализовать автозагрузку, используя путь к папке скрипта.

Пример

<?php
spl_autoload_register(function ($class) {
    $prefix = 'App\\';
    $baseDir = __DIR__ . '/src/';
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        return;
    }
    $relativeClass = substr($class, $len);
    $file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
    if (file_exists($file)) {
        require $file;
    }
});
?>

Результат: при обращении к классу App\Controller\User будет загружен файл src/Controller/User.php.

Пояснение: __DIR__ указывает на папку, где находится файл с регистрацией автозагрузчика, а $baseDir задаёт корень пространства имён. Это гарантирует правильную загрузку независимо от того, из какого скрипта вызван класс.

Ошибка: если путь содержит символические ссылки, file_exists может не сработать из-за разных представлений пути. Решение: перед проверкой применить realpath() к $baseDir.

Пример 3: Определение пути к логам относительно скрипта

Логи часто сохраняются в папку, расположенную на уровень выше корня приложения. Используя dirname(__DIR__), можно сформировать путь безопасно.

Пример

<?php
$logDir = dirname(__DIR__) . '/logs';
if (!is_dir($logDir)) {
    mkdir($logDir, 0775, true);
}
$logFile = $logDir . '/app.log';
error_log('Тестовое сообщение', 3, $logFile);
?>

Результат: в файл logs/app.log будет записано сообщение.

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

Проблема: при развёртывании проекта на разных серверах структура папок может отличаться. Рекомендуется выносить такие пути в конфигурационный файл или переменные окружения.

Пример 4: Разрешение относительных путей с помощью realpath() для безопасного include

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

Пример

<?php
$relativePath = '../config/database.php';
$absolutePath = realpath(__DIR__ . '/' . $relativePath);
if ($absolutePath !== false) {
    require $absolutePath;
} else {
    echo 'Файл не найден';
}
?>

Пояснение: realpath() разрешает все .. и симлинки, возвращая канонический путь. Если файл существует, он подключается; иначе – обработка ошибки.

Ошибка: realpath() требует, чтобы все промежуточные папки существовали. Если папка config не существует, функция вернёт false. Для включения файлов, которые могут не существовать, лучше использовать file_exists() или stream_resolve_include_path().

Пример 5: Определение пути к папке скрипта при работе в CLI

В командной строке переменная $_SERVER может быть неполной. __DIR__ всегда доступен.

Пример

<?php
// script.php в /home/user/project/bin/
$scriptDir = __DIR__;
echo "Скрипт запущен из: $scriptDir";
?>
Скрипт запущен из: /home/user/project/bin

Пояснение: в CLI __DIR__ работает так же, как в веб-среде. Это делает его универсальным решением для всех режимов работы PHP.

Папка PHP скрипта - comments

En
Php папка скрипта (php)