apache 如何以编程方式确定 PHP 中的文档根目录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/390276/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 17:04:57  来源:igfitidea点击:

How to programmatically determine the document root in PHP?

phpapacheconfiguration

提问by Kim Sullivan

Here's a problem that I've been running into lately - a misconfigured apache on a webhost. This means that all scripts that rely on $_SERVER['DOCUMENT_ROOT']break. The easiest workaround that I've found is just set the variable in some global include files that is shared, but it's a pain not to forget it. My question is, how do I determine the correct document root programatically?

这是我最近遇到的一个问题 - 虚拟主机上配置错误的 apache。这意味着所有依赖于$_SERVER['DOCUMENT_ROOT']中断的脚本。我发现的最简单的解决方法是在一些共享的全局包含文件中设置变量,但不要忘记它是一种痛苦。我的问题是,如何以编程方式确定正确的文档根目录?

For example, on one host, the setup is like this:

例如,在一台主机上,设置是这样的:

$_SERVER['DOCUMENT_ROOT'] == '/htdocs'

The real document roots are:

真正的文档根是:

test.example.com -> /data/htdocs/example.com/test
www.example.com -> /data/htdocs/example.com/www

And I'd like a script that's run from www.example.com/blog/(on the path /data/htdocs/example.com/www/blog) to get the correct value of /data/htdocs/example.com/www.

我想要一个从www.example.com/blog/(在路径上/data/htdocs/example.com/www/blog)运行的脚本来获取/data/htdocs/example.com/www.

On another host, the setup is a bit different:

在另一台主机上,设置有点不同:

$_SERVER['DOCUMENT_ROOT'] == '/srv'
test.example.com -> /home/virtual_web/example.com/public_html/test
www.example.com -> /home/virtual_web/example.com/public_html/www

Is there any solution to this? Or is the only way simply not to ever rely on $_SERVER['DOCUMENT_ROOT']and fix all the software that I'm running on my sites? Fixing this on the hosting's side doesn't seem to be an option, I've yet to encounter a host where this is was configured correctly. The best I got was a document root pointing to www.example.com, which was at least inside open_basedir - they used yet another naming scheme, www.example.com would point to /u2/www/example_com/data/www/.

有什么解决办法吗?或者是永远不要依赖$_SERVER['DOCUMENT_ROOT']和修复我在我的网站上运行的所有软件的唯一方法?在主机端修复此问题似乎不是一个选项,我还没有遇到过正确配置的主机。我得到的最好的是一个指向 www.example.com 的文档根目录,它至少在 open_basedir 内部——他们使用了另一种命名方案,www.example.com 将指向/u2/www/example_com/data/www/.

采纳答案by Kim Sullivan

Based on http://www.helicron.net/php/:

基于http://www.helicron.net/php/

$localpath=getenv("SCRIPT_NAME");
$absolutepath=getenv("SCRIPT_FILENAME");
$_SERVER['DOCUMENT_ROOT']=substr($absolutepath,0,strpos($absolutepath,$localpath));     

I had to change the basename/realpath trick because it returned an empty string on my host. Instead, I use SCRIPT_FILENAME. This probably won't work on IIS anymore (but the original scripts that used the $_SERVER variable probably wouldn't either).

我不得不更改 basename/realpath 技巧,因为它在我的主机上返回了一个空字符串。相反,我使用SCRIPT_FILENAME. 这可能不再适用于 IIS(但使用 $_SERVER 变量的原始脚本可能也不会)。

回答by Eineki

In PHP5 there is the magic constant __FILE__that contains the absolute path of the file in which it appears. You can use it in combination with dirname to calculate the document root.

在 PHP5 中有一个魔法常量__FILE__,它包含它出现的文件的绝对路径。您可以将它与 dirname 结合使用来计算文档根。

You can put a statement like the following one in a config file

您可以在配置文件中放置如下语句

define ('DOCUMENT_ROOT', dirname(__FILE__));

this should do the trick

这应该可以解决问题

回答by Kornel

There's no need to modify all scripts.

无需修改所有脚本。

You can run PHP file before any script is run using auto_prepend_file.

您可以在使用 .php 运行任何脚本之前运行 PHP 文件auto_prepend_file

$_SERVERis just an array, you canmodify it and set correct $_SERVER['DOCUMENT_ROOT'].

$_SERVER只是一个数组,您可以修改它并设置正确的$_SERVER['DOCUMENT_ROOT'].

回答by James Cape

This is one reason why people siphon everything through a bootstrap /index.php using htaccess and/or query strings. You can use the dirname( __FILE__ )trick noted above and get the public base of your app that way.

这就是人们使用 htaccess 和/或查询字符串通过引导程序 /index.php 虹吸一切的原因之一。您可以使用dirname( __FILE__ )上面提到的技巧并以这种方式获取应用程序的公共基础。

If you're too far into it to switch to a single entry point, one thing I've seen people do is have a common header to their script which walks up the directory tree to find a file which is unique to the base dir:

如果你太深入而无法切换到单个入口点,我见过人们做的一件事是他们的脚本有一个共同的标头,它会沿着目录树向上查找一个对于基本目录来说是唯一的文件:

function findAppBase( $dir ) {
    if( file_exists( "$dir/unique_file.txt" ) ) {
        return $dir;

    return findAppBase( dirname( $dir ) );
}

$base = findAppBase( dirname( __FILE__ ) );

That code hasn't been tested, and there might be a slicker way using the vars in $_ENVor $_SERVERthat will do what you want...

该代码尚未经过测试,并且可能有一种使用 vars 的更灵活的方法,$_ENV或者$_SERVER可以执行您想要的操作...

回答by SchizoDuckie

Why not demand that your webhost configures his servers correctly?

为什么不要求您的虚拟主机正确配置他的服务器?

these kind of things tend to linger silently in your code and never get removed (but still active) until someone finally fixes the server. Thén everything will break again.

这些东西往往会在您的代码中默默地徘徊,并且在有人最终修复服务器之前永远不会被删除(但仍然活跃)。那么一切都会再次破裂。

Or, move your stuff to a host that will work. If this is broken, who knows what you will find next.

或者,将您的东西移到可以工作的主机上。如果这被打破了,谁知道你接下来会发现什么。

回答by SchizoDuckie

PHP shouldbe setting the current directory to the one the script is in, so as long as that's not broken you should be able to figure out the document root using $_SERVER['SCRIPT_FILENAME']and getcwd(). (I can't remember all the $_SERVER vars off the top of my head, there might be something in phpinfo() that's more useful.)

PHP应该将当前目录设置为脚本所在的目录,因此只要没有损坏,您应该能够使用$_SERVER['SCRIPT_FILENAME']和找出文档根目录getcwd()。(我记不起所有的 $_SERVER 变量了,phpinfo() 中可能有一些更有用的东西。)