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

Те (дешевые) Mass-Hosters нередко выполняют некоторые трюки URL-реферирования Apache, которые в основном делают THEIR Life проще, поскольку есть только ОДИН Apache V-Host с ONE Document-Root для всех общих веб-сайтов.

Чтобы найти «настоящий» документ Root в этом случае:

  • Сравните DOCUMENT_ROOT с SCRIPT_FILENAME слева направо. Если нет соответствующих компонентов Path-Components, это такой общий хост.
  • Если это такой общий хост, удалите REQUEST_URI из SCRIPT_NAME => "index.php" в вашем примере.
  • Затем: удалите результат сверху с конца SCRIPT_FILENAME => ваш DOCUMENT_ROOT (/ home / sitename / public_html /)

Редактировать (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 ) говорит серверу искать в другом месте файлы для обработки. Вам нужно будет обработать эту разницу, если вы хотите, чтобы ваш скрипт работал правильно.