Путь текущего 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.cssCSS появится в моем 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__);
Другие вопросы по тегам