TL; DR : Какие альтернативы последнему образцу кода на этой странице существуют при попытке использовать относительные ссылки на страницах, включенных в команду include
PHP?
Я пытаюсь 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
включает панель навигации, используя функцию include
PHP. Панель навигации сохраняется как /documentroot/project1/php/header.php
а css для навигации в качестве /documentroot/project1/css/style.css
. При использовании относительных ссылок (чтобы сообщить браузеру, где style.css
), браузер по-прежнему считает, что путь относится к index.php
а не header.php
, поэтому он ищет CSS в том же каталоге, что и index.php
.
Проблема: Есть несколько файлов index.php в разных каталогах, и я не хочу копировать и вставлять мою папку CSS в каждую директорию, содержащую файл index.php
.
То, что я делал в прошлом, – это использовать такую настройку:
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__));
Я думаю, что я собираюсь сделать это так.
У меня есть конфиг / папка в корне моего проекта с файлом 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);
это удаляет корень doc из полного пути каталога моего файла конфигурации, тем самым давая мне фактический путь относительно веб-корня. Если ваш файл конфигурации был в корне вашего проекта, вы должны удалить эту строку:
$dir = dirname(__DIR__);
относительный URL-адрес или где ваш скрипт расположен относительно корня документа
preg_replace('/[\\\\\\/]+/', '/', '/' . substr(__DIR__, strlen($_SERVER['DOCUMENT_ROOT'])) . '/' )