【问题标题】:PHP strange DOCUMENT_ROOTPHP 奇怪的 DOCUMENT_ROOT
【发布时间】:2011-02-15 08:32:32
【问题描述】:

所以基本上,我正在编写一个框架,作为其功能的一部分,它应该为最终开发人员提供一组完善的 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 Reseller Account(共享主机)上尝试了它,但一切都破裂了。 我已经在有问题的机器上打印出 $_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

【问题讨论】:

  • 我不明白......“预期”是什么意思?你为什么期待“/home/sitename/public_html/”?我猜您对在共享主机上将“/usr/local/apache/htdocs”作为文档根目录感到困惑,但我想这只是一个伪造的目录,b/c 他们不希望您获得更多关于他们的目录结构比必要的。
  • 阴谋论 ;),我可以使用__FILE__(例如)完美地找到结构。这就是我得到预期路径的地方。
  • 嗯,很多脚本可能会因此而中断。您是否尝试过联系 HG 并通知他们该问题?
  • 这是我的脚本应该处理的问题。

标签: php shared-hosting document-root k2f


【解决方案1】:

那些(便宜的)大容量主机经常使用一些 Apache URL 重写技巧 - 这基本上让他们的生活更轻松,因为只有一个 Apache V-Host,所有共享网站都有一个 Document-Root。

在这种情况下要找到“真正的”文档根:

  • 从左到右比较 DOCUMENT_ROOT 和 SCRIPT_FILENAME。如果没有匹配的 Path-Components,它就是这样一个共享主机。
  • 如果是这样的共享主机,请在您的示例中从 SCRIPT_NAME => "index.php" 中删除 REQUEST_URI。
  • 然后:从 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']).'/';
}

【讨论】:

  • SCRIPT_NAME 中删除REQUEST_URI 时,不要忘记REQUEST_URI 可能是“/”、“/index.php”、“/?page=2”等。重写 URL 的情况 (mod_rewrite?) REQUEST_URISCRIPT_NAME 无关。
【解决方案2】:

我会使用dirname(__FILE__)dirname(dirname(__FILE__) . '/../..') 或类似的东西来创建常量DOCUMENT_ROOT,然后使用它来代替$_SERVER['DOCUMENT_ROOT']

【讨论】:

  • 这仅适用于硬编码路径的情况,这是我一开始就试图避免的。
  • 那么使用$_SERVER['DOCUMENT_ROOT'] 有什么意义呢?即,为什么$_SERVER['DOCUMENT_ROOT'] 的无效值对您来说是个问题?对于创建路径,使用服务器提供的$_SERVER['DOCUMENT_ROOT'] 或“脚本计算”常量DOCUMENT_ROOT 并不重要。
  • 您使用了双点来正确校准路径,我不知道我在 web 目录中的位置:__FILE__ 可能是 /www/aaa/index.php 以及 /www/aaa/bbb/index.php。跨度>
  • 是的。但是如果 index.php(整个页面/系统的主入口文件)驻留在 /www/aaa/bbb 中,我希望 DOCUMENT_ROOT 指向 /www/aaa/bbb 而不是一些无意义的目录。
【解决方案3】:

文档根目录是每个虚拟主机。但是使用 UserDir(例如~sitename)告诉服务器在别处寻找要处理的文件。如果您希望脚本正常工作,则需要处理这种差异。

【讨论】:

  • 我如何找到它?也就是说,我可以通过让我的脚本比较DOCUMENT_ROOTSCRIPT_FILENAME 来了解这个问题,但是我怎样才能找到真正的DOCUMENT_ROOT
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 2014-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
相关资源
最近更新 更多