How to get the root of your site, regardless of the folder depth of your script while taking into account any Aliases your webserver might have?
Say, for example, that you have in your apache conf the following lines:
DocumentRoot /var/www/htdocs Alias /phpsite /var/www/mysite
That means that your PHP site resides in /var/www/mysite, while rest of your web resides in /var/www/htdocs. How will your PHP scripts know that /phpsite portion, without hardcoding this into scripts, when they do not know how many levels deep in directory structure they themselves are in your site (e.g /phpsite/posts/update.php).
First, if you already don’t have, create a script (call it what ever you like, e.g. config.php) somewhere in your site folder. Preferred is at the top level, but subfolders work too (more on this later).
Secondly, put the following inside that file:
$wwwroot = "http://" . $_SERVER['SERVER_NAME'] . str_replace( str_replace( dirname(__FILE__), "", $_SERVER['SCRIPT_FILENAME']), "", $_SERVER['SCRIPT_NAME']);
If you placed your config.php in some subfolder, then you have to multiply the dirname() calls for every subfolder level. E.g if your config.php is in conf/config.php, i.e second level, you need 2 dirname() calls and your 4th line should look like:
dirname(dirname(__FILE__))
Third, include this file in every script, even in subfolders and prepend to links:
require_once "../config.php"; echo "Some script";
Voila!
Under the hood
What this script does is actually rather simple string algebra. The contents of those special variable is as follows:
$_SERVER['SERVER_NAME'] # => example.com __FILE__ # => /var/www/mysite/config.php - the name of the script where this is written $_SERVER['SCRIPT_FILENAME'] # => /var/www/mysite/dir/script.php - the full path to script that included config.php $_SERVER['SCRIPT_NAME'] # => /phpsite/dir/script.php - the URL path of the script that included config.php
You might already start to grasp what we’re about to do. Leaving aside the obvious hostname part, what the str_replace part does is the following:
- calculate filesystem path to the base of the site: dirname(__FILE__): /var/www/mysite/config.php => /var/www/mysite
- substract this path from the SCRIPT_FILENAME => /var/www/mysite/dir/script.php => /dir/script.php
- substract the result from the URL SCRIPT_NAME => /phpsite/dir/script.php => /phpsite
This method works even if you change the Alias or remove it altogether.