PHP странный DOCUMENT_ROOT
Итак, в основном, я пишу фреймворк, и как часть его возможностей, он должен предоставить конечному разработчику набор хорошо известных URI / путей.
Некоторые из этих двух путей используют $_SERVER['DOCUMENT_ROOT']
:
/**
* Absolute filesystem path to web root install (aka docroot).
* @example "C:/wamp/www" OR "/home/visitgoz/public_html/"
*/
CFG::set('ABS_WWW',
str_replace(
$tmpseps,
DIRECTORY_SEPARATOR,
truepath($_SERVER['DOCUMENT_ROOT']).'/'
)
);
/**
* K2F path relative to web root.
* @example /K2F/
*/
CFG::set('REL_K2F',
str_replace(
array('//','\\'),
'/',
str_replace(CFG::get('ABS_WWW'),'/',CFG::get('ABS_K2F'))
)
);
Код был настроен для работы как в Linux, так и в Windows. По-видимому, большую часть времени он работает в Linux, а на VPS - практически без проблем.
Однако, в последнее время, я попробовал это на учетной записи реселлера HG (виртуальный хостинг), и все это распалось. Я распечатал данные внутри $_SERVER на проблемном компьютере:
Array
(
** [DOCUMENT_ROOT] => /usr/local/apache/htdocs
[GATEWAY_INTERFACE] => CGI/1.1
[HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8
[HTTP_ACCEPT_CHARSET] => ISO-8859-1,utf-8;q=0.7,*;q=0.7
[HTTP_ACCEPT_ENCODING] => gzip,deflate
[HTTP_ACCEPT_LANGUAGE] => en-gb,en;q=0.5
[HTTP_CONNECTION] => keep-alive
[HTTP_COOKIE] => <snip>
[HTTP_HOST] => <snip>
[HTTP_KEEP_ALIVE] => 115
[HTTP_USER_AGENT] => <snip>
[PATH] => /bin:/usr/bin
[QUERY_STRING] =>
[REDIRECT_STATUS] => 200
[REMOTE_ADDR] => <snip>
[REMOTE_PORT] => 49262
[REQUEST_METHOD] => GET
[REQUEST_URI] => /~sitename/
** [SCRIPT_FILENAME] => /home/sitename/public_html/index.php
[SCRIPT_NAME] => /~sitename/index.php
[SERVER_ADDR] => <snip>
[SERVER_ADMIN] => <snip>
[SERVER_NAME] => <snip>
[SERVER_PORT] => 80
[SERVER_PROTOCOL] => HTTP/1.1
[SERVER_SIGNATURE] =>
Apache mod_fcgid/2.3.5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 Server at <snip> Port 80
[SERVER_SOFTWARE] => Apache mod_fcgid/2.3.5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635
[UNIQUE_ID] => TVox-Eo1Z8IAAG1kAh4AAAEZ
[PHP_SELF] => /~sitename/index.php
[REQUEST_TIME] => 1297756668
[argv] => Array
(
)
[argc] => 0
)
И моя машина:
Array
(
[HTTP_AUTHORIZATION] =>
[HTTP_HOST] => <snip>
[HTTP_USER_AGENT] => <snip>
[HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8
[HTTP_ACCEPT_LANGUAGE] => en-gb,en;q=0.5
[HTTP_ACCEPT_ENCODING] => gzip,deflate
[HTTP_ACCEPT_CHARSET] => ISO-8859-1,utf-8;q=0.7,*;q=0.7
[HTTP_KEEP_ALIVE] => 115
[HTTP_CONNECTION] => keep-alive
[PATH] => <snip>
[SystemRoot] => C:\Windows
[COMSPEC] => C:\Windows\system32\cmd.exe
[PATHEXT] => .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
[WINDIR] => C:\Windows
[SERVER_SIGNATURE] =>
[SERVER_SOFTWARE] => Apache/2.2.11 (Win32) PHP/5.3.1
[SERVER_NAME] => <snip>
[SERVER_ADDR] => <snip>
[SERVER_PORT] => 80
[REMOTE_ADDR] => <snip>
** [DOCUMENT_ROOT] => C:/wamp/www/
[SERVER_ADMIN] => admin@localhost
** [SCRIPT_FILENAME] => C:/wamp/www/K2F/cms/cms-joomla-1.5/index.php
[REMOTE_PORT] => 49947
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_PROTOCOL] => HTTP/1.1
[REQUEST_METHOD] => GET
[QUERY_STRING] =>
[REQUEST_URI] => /K2F/cms/cms-joomla-1.5/
[SCRIPT_NAME] => /K2F/cms/cms-joomla-1.5/index.php
[PHP_SELF] => /K2F/cms/cms-joomla-1.5/index.php
[REQUEST_TIME] => 1297758541
)
** Части, которые вы должны прочитать, должны отлично объяснить мою проблему.
Таким образом, в основном, ожидаемый DOCUMENT_ROOT
является /home/sitename/public_html/
, но вместо этого я получил /usr/local/apache/htdocs
,
Ох, и извините, если я был слишком многословен;)
Редактировать:
getcwd()
=> /home/visitgoz/public_html
__FILE__
=> /home/visitgoz/public_html/K2F/config.php
3 ответа
Эти (дешевые) массовые хостеры нередко совершают некоторые трюки Apache по перезаписи URL-адресов, которые в основном облегчают их жизнь, поскольку есть только ОДИН V-хост Apache с ОДНЫМ Document-Root для всех общих веб-сайтов.
Чтобы найти "настоящий" документ Root в этом случае:
- Сравните DOCUMENT_ROOT с SCRIPT_FILENAME слева направо. Если нет подходящих Path-Components, это такой общий хост.
- Если это такой общий хост, удалите REQUEST_URI из SCRIPT_NAME => "index.php" в вашем примере.
- Затем: удалите результат сверху из конца SCRIPT_FILENAME => ваш DOCUMENT_ROOT (/ home / sitename / public_html /)
Edit (Christian Sciberras): Это правильный ответ, но в нем нет кода, который я должен был написать в любом случае, так что здесь идет:
if(strpos($_SERVER['SCRIPT_FILENAME'],$_SERVER['DOCUMENT_ROOT'])===false){
// how it works on reseller accounts...
$path=str_common(getcwd(),__FILE__);
}else{
// how it normally works...
$path=truepath($_SERVER['DOCUMENT_ROOT']).'/';
}
Я хотел бы использовать dirname(__FILE__)
, dirname(dirname(__FILE__) . '/../..')
или что-то подобное, чтобы создать постоянную DOCUMENT_ROOT
который затем будет использоваться вместо $_SERVER['DOCUMENT_ROOT']
,
Корень документа для каждого виртуального хоста. Но используя UserDir (например, ~sitename
) указывает серверу искать в другом месте файлы для обработки. Вам нужно будет справиться с этой разницей, если вы хотите, чтобы ваш скрипт работал правильно.