Путь текущего PHP-скрипта относительно корня документа
TL; DR: Какие альтернативы последнему примеру кода на этой странице существуют при попытке использовать относительные ссылки на страницах, включенных в PHP include
команда?
Я пытаюсь include()
файл, который ссылается на .css
документ, проблема в том, что мне нужно включить этот файл из нескольких (разных) каталогов. Моя структура каталогов выглядит примерно так:
www
├── (getpath.php)
│
├── css
│ └── style.css
├── php
│ └── header.php
└── content
├── index.php
└── posts
└── index.php
(Я в том числе header.php
в обоих index.php
файлы. header.php
это файл, который относится к style.css
(который должен найти браузер). Пример: при использовании ../css/style.css
CSS появится в моем content/index.php
но не в моем content/posts/index.php
потому что браузер ищет content/css/index.php
.)
Веб-сайт также должен работать, если он находится в подкаталоге корня документа, а не в самом корне документа. По этой причине я не могу просто использовать /css/style.css
(относительно корня сервера) для ссылки на мою таблицу стилей CSS.
Я думаю (пожалуйста, исправьте меня, если я ошибаюсь!), Что самый простой способ сообщить браузеру, где найти документ CSS, это, вероятно, указать путь относительно корня документа. Поскольку я ожидаю, что мой веб-сайт будет находиться в подкаталоге корня документа (и хочу избежать использования config
файл для хранения подкаталога), мне нужно выяснить относительный путь подкаталога, в котором находится веб-сайт. Моя идея заключалась в том, чтобы разместить файл с именем getpath.php
в корневой директории моего сайта (не в корне документа). В этом файле я написал следующее:
<?php
define('PROJECT_SUBDIRECTORY', $_SERVER['PHP_SELF']);
?>
Однако я заметил, что это дает мне относительный каталог PHP-файла, который пользователь запросил в браузере (например, content/index.php
) вместо включенного файла (getpath.php
). Я также прочитал это PHP_SELF
основывается на REQUEST_URI
, который не был бы в безопасности. Я нашел это решение здесь:
define('PROJECT_DIR', preg_replace('/^' . preg_quote($_SERVER['DOCUMENT_ROOT'], '/') . '/', '', __DIR__));
Это прекрасно работает, но мне интересно, есть ли "лучший" способ сделать это. Мне не удалось найти переменную для этого - действительно ли приведенное выше решение - единственный способ сделать это?
Должен ли я использовать предыдущий пример кода или есть лучший способ?
Должен ли я изменить структуру каталогов? Как другие люди решают эту проблему?
Изменить: у меня есть несколько (полностью независимых) веб-сайтов на моем веб-сервере, все они находятся в подкаталогах корня документа (например, /documentroot/project1/
, /documentroot/project2/
...)
Я пытаюсь заставить сайты работать в подкаталогах. Я мог бы явно отправить CSS в браузер через /css/style.css
, но это не работает, если веб-сайт находится в подкаталоге. Я также хочу избегать использования файла конфигурации для указания пути моего проекта относительно корня документа.
Другое редактирование: проблема в том, что каждый php файл в моем проекте /documentroot/project1
включает в себя панель навигации с использованием PHP include
функция. Панель навигации сохраняется как /documentroot/project1/php/header.php
и CSS для Navbar как /documentroot/project1/css/style.css
, При использовании относительных ссылок (указать браузеру, где style.css
есть), браузер все еще думает, что путь относительно index.php
скорее, чем header.php
, поэтому он ищет CSS в том же каталоге, что и index.php
,
Проблема: существует несколько файлов index.php в разных каталогах, и я не хочу копировать и вставлять мою папку CSS в каждый отдельный каталог, содержащий index.php
файл.
4 ответа
В прошлом я использовал такую настройку:
define('DIR_BASE', dirname( __FILE__ ).'/');
define('DIR_SYSTEM', DIR_BASE.'app/');
etc.
Это будет помещено в корень файла вашего проекта, что даст вам доступ к другим областям вашей файловой структуры относительно корня.
Для вашего случая это будет выглядеть так:
define('DIR_BASE', dirname( __FILE__ ).'/');
define('DIR_CSS', DIR_BASE.'css/');
define('DIR_PHP', DIR_BASE.'php/');
define('DIR_CONTENT' DIR_BASE.'content/');
Это будет идти в getpath.php в вашем корне, и даст вам возможность ссылаться на любой файл или каталог, независимо от того, где он находится в структуре каталога (обязательно включите его, где бы вы их не использовали). Вам не нужно менять структуру каталогов или что-то в этом роде, и вам не нужно беспокоиться о каких-либо уязвимостях с чем-то вроде этого, так как он внутренний.
Редактировать Я продолжаю возвращаться к структуре системы. Это многосайтовая система, которая использует тот же CSS-код? Если нет, то каково обоснование того, чтобы структура каталогов была выстроена следующим образом? Можете ли вы дать немного больше деталей, пожалуйста?
Похоже, лучший способ сделать это удаление $_SERVER['DOCUMENT_ROOT']
от __DIR__
, как я уже упоминал в оригинальном вопросе.
define('PROJECT_DIR', preg_replace('/^' . preg_quote($_SERVER['DOCUMENT_ROOT'], '/') . '/', '', __DIR__));
Я думаю, что я просто собираюсь сделать это так.
Относительный URL или где ваш скрипт расположен относительно корня документа
preg_replace('/[\\\\\\/]+/', '/', '/' . substr(__DIR__, strlen($_SERVER['DOCUMENT_ROOT'])) . '/' )
У меня есть папка config/ в корне моего проекта с файлом main.php, я использую это:
$root = $_SERVER['DOCUMENT_ROOT'];
$dir = dirname(__DIR__);
$root = str_replace("\\","/",$root);
$dir = str_replace("\\","/",$dir);
$web_dir = str_replace($root,'',$dir);
if ($web_dir!=='') { $web_dir = '/'.$web_dir; }
define('DIR',$web_dir);
это удаляет корень документа из полного пути к каталогу моего конфигурационного файла, таким образом давая мне фактический путь относительно веб-корня. Если ваш конфигурационный файл был в корне вашего проекта, вы бы удалили эту строку:
$dir = dirname(__DIR__);