This can be a bit confusing because $_SERVER['DOCUMENT_ROOT']
is set by PHP based on the web server, the Web Root
is set by the web server (Apache or IIS), and the URL
uses a similar notation to the two when delivering and accessing files in browsers. If the web root is above the domain name in a folder it can be confusing if you're using a single /
to access the root
directory in HTML.
I'm not going to get into server config files for these, only PHP and URLs in client-side code.
PHP Includes
Because [web] hosts can change your directory structure by moving your web directory to a new server (think shared hosting), or because you may need to use a development server in a different environment than the production server, the worst method when linking to files is to use the full "hard-coded" path to the file.
//Example of WORST METHOD
include('/usr/local/etc/www/html/includes/config.php');
As long as all of your files are above the document root or will remain in the same general location on a different server you *can* include()
with previous directory notation. When you're setting an include()
or require()
with dot notation the dots are relative to the file using the notation, so it can become a bit trickier to follow.
include('../header.php');
If inside of the header you are including a "config.php" in the previous directory, it would say:
include('../config.php');
In actuality the real file paths could be:
$_SERVER['DOCUMENT_ROOT'].'/some_folder/header.php';
$_SERVER['DOCUMENT_ROOT'].'/config.php';
Best practice
Keep the includes INTUITIVELY all in one place. If header is in the "includes" folder just inside of the document root you can do something like this:
$root = $_SERVER['DOCUMENT_ROOT'];
//folder for functions, headers and so forth
$includes = $root.'/includes/';
//For database passwords and other code that should
//not be above the document root.
$safe = $root.'/../safe/';
require_once($safe.'db_connect.php');
require_once($includes.'config.php');
require_once($includes.'header.php');
Anytime you would need to include some other file you would only use the $includes
var.
Another problem with previous directory notation is when you're making nested directories and including the same file it becomes a bit difficult to move a folder or follow the code.
I'm always editing sites that have code like:
include ('../../../shell.php');
Not a problem with a shell page... but if you have multiple configs (I've also run into this). Working with more than one developer this can get out of hand because all files open in a text editor say config.php
and something will eventually be overwritten.
//Site Config
include('../../config.php');
//Project Config
include('../config.php');
Link Paths and URLs in client-side code
There is a difference between URLs and File Paths. When you're accessing files on a local machine with PHP it's best to use file paths.
$path = $_SERVER['DOCUMENT_ROOT'].'/includes/header.php'; //or
$path = '../includes/header.php';
/*or if you're on Windows*/
$path = $_SERVER['DOCUMENT_ROOT'].'\includes\header.php\;
When you're using a client-side language like HTML, CSS, or Javascript you want to use URLs. A URL can be also accessed without writing out the full URL above root and it looks similar:
$link = 'http://www.domain.com/css/site.css'; /*or*/
$link = '/css/site.css';
Document root in HTML, CSS, and Javascript is simply a /
character.