Настройка корневого пути WWW для PHP на сервере
Основное решение: настройка DocumentRoot в Apache или root в Nginx
Наиболее эффективный способ определить корневую директорию WWW для PHP - задать правильный DocumentRoot (Apache) или root (Nginx). Это напрямую влияет на значение $_SERVER['DOCUMENT_ROOT'] и определяет, из какой папки сервер отдаёт файлы.
Для Apache отредактируйте файл виртуального хоста (например, /etc/apache2/sites-available/example.conf):
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/example/public_html
<Directory /var/www/example/public_html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Для Nginx в блоке server (файл /etc/nginx/sites-available/example):
server {
listen 80;
server_name example.com;
root /var/www/example/public_html;
index index.php index.html;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
}
Пояснение: DocumentRoot или root указывают, где искать файлы для данного домена. PHP-скрипты выполняются относительно этой папки. Изменяя эту директиву, вы меняете корень WWW для проекта.
Типичные ошибки
- Несовпадение путей: если DocumentRoot указан неверно, сервер выдаёт 404.
- Забыли перезагрузить сервер:
sudo systemctl reload apache2илиsudo nginx -s reload. - Проблемы с правами доступа: папка должна быть доступна для чтения веб-серверу (обычно пользователь www-data).
Как изменить корень WWW с помощью PHP built-in server для разработки?
Встроенный сервер PHP позволяет быстро задать корневую директорию через аргумент командной строки:
php -S localhost:8080 -t /home/user/myproject/public
Флаг -t определяет корневую папку. Все запросы будут обрабатываться относительно неё. Это удобно для изолированной разработки без полноценного веб-сервера.
Проблемы
- Не подходит для production - нет многопоточности и оптимизации.
- Не поддерживает .htaccess.
Как задать корень WWW через символическую ссылку на папку проекта?
Можно создать символическую ссылку в существующей корневой директории (например, /var/www/html) на реальную папку проекта:
ln -s /home/user/project/public /var/www/html/myproject
Теперь URL http://example.com/myproject ведёт к файлам из /home/user/project/public. PHP-скрипты будут видеть корень как /var/www/html, но содержимое будет браться из связанной папки. Этот метод полезен, когда нужно временно подключить проект без изменения конфигурации сервера.
Типичные ошибки
- Символическая ссылка только для чтения, если не настроен FollowSymLinks (включите его в конфигурации Apache или Nginx).
- Путаница с относительными путями в PHP:
$_SERVER['DOCUMENT_ROOT']всё равно указывает на/var/www/html, а не на реальную папку.
Как изменить корень WWW с помощью Alias в Apache или Nginx?
Директива Alias (Apache) или alias (Nginx) позволяет привязать URL-путь к произвольной директории, не меняя DocumentRoot. Пример для Apache:
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
Alias /blog /home/user/blog/public
<Directory /home/user/blog/public>
Require all granted
</Directory>
</VirtualHost>
Теперь /blog ведёт к другой корневой директории. Для Nginx:
location /blog/ {
alias /home/user/blog/public/;
index index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
Этот вариант подходит, когда нужно разместить несколько проектов под одним доменом, не меняя корневой DocumentRoot.
Ошибки
- В Nginx alias и location с регулярными выражениями могут конфликтовать, нужно аккуратно указывать пути.
- PHP не всегда корректно определяет
$_SERVER['DOCUMENT_ROOT']для алиаса - значение остаётся родительским корнем.
Как задать корень WWW через chroot или open_basedir для изоляции PHP?
Директива open_basedir в php.ini ограничивает файлы, к которым PHP имеет доступ. Это не меняет DocumentRoot, но влияет на то, какие файлы скрипты могут читать/писать. Пример:
open_basedir = /var/www/myproject:/tmp
Такая настройка полезна для безопасности: если скрипт попытается обратиться к файлу вне указанных папок, PHP выдаст ошибку. Однако корень WWW остаётся прежним. Полноценная смена корня возможна через chroot для процесса веб-сервера, но это сложная конфигурация, выходящая за рамки статьи.
Типичные ошибки
- Слишком строгий open_basedir может сломать работу системных библиотек.
- Необходимо указывать все необходимые пути, включая папки для сессий и логов.
Расширенные примеры и результаты
Пример 1: Проверка значения DOCUMENT_ROOT в PHP
Создайте файл info.php с содержимым:
<?php
echo "Document Root: " . $_SERVER['DOCUMENT_ROOT'] . "\n";
echo "Script filename: " . $_SERVER['SCRIPT_FILENAME'];
?>
Результат при стандартной настройке (DocumentRoot = /var/www/html):
Document Root: /var/www/html Script filename: /var/www/html/info.php
После изменения DocumentRoot в конфигурации на /var/www/example/public результат изменится соответствующим образом.
Пример 2: Запуск встроенного PHP-сервера с явным корнем
mkdir -p /tmp/test_php/public
cd /tmp/test_php
echo "<?php echo 'Hello from ' . \$_SERVER['DOCUMENT_ROOT']; ?>" > public/index.php
php -S localhost:8080 -t public/
Откройте браузер http://localhost:8080. Результат:
Hello from /tmp/test_php/public
Вывод показывает, что корнем стала папка public. Этот способ идеален для быстрой разработки.
Пример 3: Настройка Alias в Nginx с демонстрацией DOCUMENT_ROOT
Конфигурация Nginx:
server {
listen 80;
server_name example.com;
root /var/www/main;
location /sub/ {
alias /var/www/sub/;
index index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
}
Поместите info.php в /var/www/sub. Результат при запросе /sub/info.php:
Document Root: /var/www/main Script filename: /var/www/sub/info.php
Обратите внимание: DOCUMENT_ROOT остаётся родительским корнем, а SCRIPT_FILENAME берётся из алиаса. Это важная особенность, которую нужно учитывать при разработке.
Пример 4: Символическая ссылка и FollowSymLinks в Apache
Создайте символическую ссылку в DocumentRoot:
sudo ln -s /home/user/other_project /var/www/html/other
В конфигурации виртуального хоста Apache должна быть опция:
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
Теперь запрос http://example.com/other/index.php выполнит скрипт из /home/user/other_project. Проверка DOCUMENT_ROOT:
echo $_SERVER['DOCUMENT_ROOT']; // /var/www/html
Корень не изменился, но файлы доступны. Убедитесь, что права доступа у www-data на /home/user/other_project разрешены.
Пример 5: Использование open_basedir для ограничения корня PHP
В файле /etc/php/8.1/apache2/php.ini (или fpm/php.ini) добавьте:
open_basedir = /var/www/myproject:/tmp
Перезагрузите PHP-FPM или Apache. После этого PHP-скрипты из проекта /var/www/myproject смогут обращаться только к файлам внутри этой папки и /tmp. Попытка прочитать /etc/passwd вызовет ошибку:
Warning: file_get_contents(): open_basedir restriction in effect. File(/etc/passwd) is not within the allowed path(s)
Это не меняет корень WWW, но эффективно изолирует файловые операции.
Пример 6: Настройка нескольких корней через VirtualHost (Apache) для разных проектов
ServerName site1.com
DocumentRoot /var/www/site1
ServerName site2.com
DocumentRoot /var/www/site2
Каждый проект имеет свой независимый корень WWW. Для Nginx аналогично используются разные блоки server.