How to programmatically determine the root of a document in PHP?

Here's the problem I have been facing lately - a misconfigured apache on the web host. This means that all scripts that rely on $_SERVER['DOCUMENT_ROOT'] break. The easiest workaround I found just sets a variable in some publicly accessible files, but it hurts not to forget about it. My question is: how can I correctly determine the root directory of a document?

For example, on one host, the installation looks like this:

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

Real document roots:

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

And I would like the script to be run from www.example.com/blog/ (on the path /data/htdocs/example.com/www/blog ) to get the correct value /data/htdocs/example.com/www .

On another host, the installation is slightly 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? Or is this the only way to simply not rely on $_SERVER['DOCUMENT_ROOT'] and fix all the software that I run on my sites? Fixing this on the hosting side does not seem to be an option; I have not yet encountered the host where it was configured correctly. The best I got is the root of the document pointing to www.example.com, which was at least inside open_basedir - they used another naming scheme, www.example.com will point to /u2/www/example_com/data/www/ .

+6
php apache configuration
source share
6 answers

Based on 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 . It probably won't work on IIS anymore (but the source scripts that used the $ _SERVER variable probably won't either).

+2
source share

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

You can put instructions in the configuration file as shown below:

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

this should do the trick

+7
source share

No need to change all scripts.

You can run the PHP file before running any script using auto_prepend_file .

$_SERVER is just an array, you can change it and set the correct $_SERVER['DOCUMENT_ROOT'] .

+3
source share

This is one of the reasons why people iterate over everything via bootstrap / index.php using htaccess and / or query strings. You can use the dirname( __FILE__ ) trick mentioned above, and thus get your applicationโ€™s public database.

If you go too far to it to switch to a single entry point, one thing I have seen is to make a general header for your script, which picks up a directory tree to find a file that is unique in the base directory:

 function findAppBase( $dir ) { if( file_exists( "$dir/unique_file.txt" ) ) { return $dir; return findAppBase( dirname( $dir ) ); } $base = findAppBase( dirname( __FILE__ ) ); 

This code has not been tested, and could be using slicker using vars in $_ENV or $_SERVER , which will do what you want ...

+2
source share

PHP should set the current directory to the one in which the script is located, so that until it is broken, you can determine the document root using $_SERVER['SCRIPT_FILENAME'] and getcwd() . (I can't remember everything vs $ _SERVER from the head, maybe something in phpinfo () would be more useful.)

0
source share

Why not require your web host to configure the servers correctly?

these things, as a rule, freeze in your code and are never deleted (but still active) until someone finally fixes the server. Everything will break again.

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

0
source share

All Articles