PHP Include from Root

Published by Chris Coyier

When I reference images, I almost always do something like this:

<img src="/images/logo.png" alt="logo" />

That is a relative file path, but it begins at the root public directory of the site. That way it always references the same location, no matter what directory that code snippet ends up in. If it didn't begin with that "/", it would be a relative file path still but it would the location would depend on what directory you were in at the time. Might work fine when you are at /index.php, but if that moves to /contact/, the file path breaks because the images folder is in the root not in /contact/.

Common sense stuff.

But this gets a little more complicated when dealing with a server side language like PHP. You can also do includes with PHP like this:

<?php include("header.php"); ?>

Because it doesn't begin with a "/", it suffers from the same problem our images example suffered from. If that include code moves to a different directory, the reference can be broken. But with PHP, simply using that beginning "/" will not work, which can be mighty confusing.

The problem is that PHP can see a bit "deeper" into your servers file system than HTML can. For example, the public web directory of CSS-Tricks actually lives at "/var/www/vhosts/css-tricks.com/httpdocs" on my server. So when you do an include with a "/" at the beginning, it looks WAY down deeper than you are intending it to. You actually want it to look in that public web directory. In my case, "httpdocs".

In order to get this functionality back and have relative file paths that do not change, use this bit of PHP smartness:

<?php 
   $path = $_SERVER['DOCUMENT_ROOT'];
   $path .= "/common/header.php";
   include_once($path);
?>

Basic stuff for all you programmers but that one had me stumped for ages.

Another Technique

Read Brian Vanderberg writes in:

I have found that in some environments DOCUMENT_ROOT does not seem to be properly set. I have devised a way that is independent of the server, and whether the hosting provider provides the ability to set an include or auto-prepend path as well.

Each directory contains a 'meta' file called '__php__.php' (or whatever one wants to call it). For any files in that directory, they simply include it as <?php include('__php__.php'); ?>. The file itself simply includes the one in the parent directory all the way up to the site root. The file in the site root then can include other files, a simply way of auto-including files even if a service provider does not support it, and also define a variable such as 'SITE_ROOTDIR', which can then be used later. If the document files are moved to another directory, they will still include the __php__.php file in that directory and still get the SITE_ROOTDIR constant from the top __php__.php file.

I also do something similar for a simple navigation bar, where each directory has a __navbar__.php file, and each page simply includes it at the correct location and it can include parent navigation elements and define its own navigation elements.

One advantage of this is that a part of the site can be sectioned in a sub-directory, and still get the root of that part, even if it isn't the actual document root. A disadvantage is that it may slow down while doing all the includes on a site with heavy traffic.

Yet another:

<?php set_include_path( get_include_path() . PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT'] ); ?>