Поэтому в основном я пишу фреймворк, и, как часть его функций, он должен предоставить набор устоявшихся 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
Те (дешевые) Mass-Hosters нередко выполняют некоторые трюки URL-реферирования Apache, которые в основном делают THEIR Life проще, поскольку есть только ОДИН Apache V-Host с ONE Document-Root для всех общих веб-сайтов.
Чтобы найти «настоящий» документ Root в этом случае:
Редактировать (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
) говорит серверу искать в другом месте файлы для обработки. Вам нужно будет обработать эту разницу, если вы хотите, чтобы ваш скрипт работал правильно.