Relative and absolute paths, in the file system and on the web server.
- The difference between absolute and relative paths
- Absolute paths
- Relative paths
- Document root
- Web server paths
- Current working directory
- Console scripts. Single entry point
- Helpful PHP commands and constants
- Comments (12)
Your site exists in two realms at once: the real and the virtual one.
For the site visitors it's entirely a virtual server, which in many ways is different from a real one. There are no files for starter. I know, it's hard to believe at first, but it's a fact. In the address like
file.html is not a file. It's a part of URI, a virtual resource. There could be or could be not a real file with such a name, but it doesn't matter. Your browser cannot know that, and don't need to. All it needs to know is an address.
For the site developer, on the other hand, their site is a certain program running on a particular server, on the very real computer with HDD, files and directories. And your PHP script, while reading data files or including other scripts, is working with such real files that exist on the physical medium.
So this dualism is the root of many problems.
PHP users confuse these matters badly at first, doing things like being unable to locate an existing file, confusing hyperlinks with files, including local files via HTTP and such.
However, to sort these things out all you need is to grasp just two simple concepts:
- The difference between absolute and relative paths.
- The difference between the root of the web server and the filesystem root.
The difference between absolute and relative paths
It's fairly simple.
- If the path is built starting from the system root, it is called absolute.
- If the path is built starting from the current location, it is called relative (which makes sense, as it is relative to our present position)
It's exactly the same as with the real life directions. Given the absolute address, a postal one, like "7119 W Sunset Blvd West Hollywood, CA 90046" you can find the location from anywhere. However, given the relative directions, like "keep three blocks this way and then and turn to the right" would work from the current location only, otherwise sending you astray.
So it goes for the paths in the computer world: given the absolute address, you can always get to the place, no matter from where you started. Whereas relative path is tricky, and should be used with caution, only when you positively know where you are at the moment.
So again: an absolute path is one starting from the system root
Some absolute path examples:
Note that in Unix-like systems (and web-servers) the root is defined as a slash -
/. And this is very important to know. It is not just a marker, but already a full qualified address, a path. Type
cd / in your unix console and you will get to the root directory. Exactly the same is true for all web servers. So you can tell that in the
http://example.com/ address the trailing slash is not for the decoration but a regular address itself - the address of the home page.
On Windows, the filesystem doesn't have the common root for the whole system but split between disks, so an absolute paths starts from the drive letter. Whereas each disk has its own root, which is a backslash -
\. So you can type
cd \ and get to the root of the current disk.
So you can tell that windows is rather confusing, but for the simplicity we would pretend that we have only one disk, and within its boundaries the rules are pretty much the same as in Unix.
So now you can tell an absolute path from a relative one - it is starting from the root, which is:
- on a Unix file system it's
- on a web serer it's again
- on Windows it's either
\(for the current disk) or
If you don't supply the root, it means that your path is relative.
The simplest example of relative path is just a file name, like
index.html. So one should be careful with relative paths. If your current directory is
index.html would be one, but if you switch it to
/contacts/ then it will be another.
Other relative path examples:
./file.php(the file is in the current folder. The same as just
images/picture.jpg(the file is in the images folder that is in the current directory)
../file.php(file is in the folder that is one level higher than the current directory)
../../file.php(file is in the folder that is two levels higher than the current directory)
What you ought to know is that the system, when encountered a relative path, always builds it up to the absolute one. Both web-server and file system are doing that but different ways. So, let's learn them.
This is the most interesting part. There is a point where the real world meets the virtual one.
Imagine there is a file like
While on the web-server its address is
And here the point can be clearly seen: there is a part, common for both addresses:
/forum/index.php, which is the very source of confusion.
For the browser, this path is perfectly absolute, starting from the root of the web-server.
Whereas for the script it's only a part of the full path - the filesystem path. And if you try to use it in PHP it will result in a failure: there is no
/forum/ catalog on the HDD!
To get the working path to this file, we have to add the missing part. In our example it's
/var/www/site, which is called
DOCUMENT_ROOT and is the most important configuration option for the file system interactions. In PHP you can access it via
So now you can tell that to make any file system path work, it should be absolute and built using
DOCUMENT_ROOT. So a correct PHP code to access
/forum/index.php from PHP would be
$path = $_SERVER['DOCUMENT_ROOT'] . "/forum/index.php";
here we are using web-server part of the path, prepending it with the document root. Voila!
Web server paths
are much simpler.
Like it was said before, for the browser, there are no files on the server. A site user never has an access to the server's file system. For the browser, there is a site root only. Which is constant and always simply a slash.
Therefore, to make an HTML link absolute, just build it from the site root - and you will never see a 404 error for the existing file again!
Imagine your site has two sections,
and in the
info.php you want to link to
vacancy.php. If you make it as is,
<a href=vacancy.php>, then browser won't find it! Remember, it always tries to build up the link to the full one, using the current location, which is
/about/ and so the resulting path is
/about/vacancy.php which is wrong. To make it right, we have to make this link absolute, starting from the site root:
So it goes for all the internal links on the site - images, js and css files, hyperlinks or any other resource that can be clicked on or loaded on the page.
For the local resources it's better to make it path only, without protocol and domain - like
/job/vacancy.php. Whereas for the external resources these attributes are obligatory, and so it should be a fully qualified URL like
Current working directory
The current working directory (also current directory, working directory, CWD) is the key element in relative paths. It's the directory, from which relative paths being built up.
On a web-server, it's a directory, where the requested php file stays. So if you are requesting an URL like
http://example.com/about/index.php, the current working directory would be:
/aboutfor the browser
/var/www/html/aboutfor PHP/filesystem (given the document root is
therefore, all relative paths in the HTML on that page will be interpreted by browser as starting from
- a link
<a href=history.php>will be requested as /about/history.php
- an image
<img src=logo.png>will be requested as /about/logo.png
And likewise, for PHP all relative paths are starting from
In a console, the PHP's current working directory is equal to the shell's current directory. It means that while in
/home/user and calling
php folder/file.php command, the CWD will be still
You can get the current working directory using
getcwd() function or change it using
Console scripts. Single entry point
It's a pity, but for the console scripts our useful
$_SERVER['DOCUMENT_ROOT'] variable is unavailable. So we are bound to use paths relative to the calling script, derived from the current script's location.
For example, if your application is hosted in
/var/www/app and there are two subfolders,
/var/www/app/config, and you want to access the latter from the former, you can write the following code:
$config_path = __DIR__.'/../config/settings.php';
Although technically absolute (starting from a slash), this path is essentially relative to the calling script, because if the calling script will be moved into another directory, it won't find the configuration file anymore.
This is why it is recommended to use a single entry point for your application. Or - as in our case - two entry points, one for web requests and one for console commands.
So for our fictional application we would have three files - an entry point for the web front, an entry point for console applications and a bootstrap file:
Then we could write the following code (among other things) in
to define the
ROOT_DIR constant that contains the path to our application's root directory (which is directly above the
And then in both
to make all the bootstrap stuff available, including the ROOT_DIR constant. From now on we can use it to build absolute paths starting from the root directory (as long as our scripts are called through the entry point either web or console one):
Example implementations can be found in Laravel's Artisan or Symfony Console.
Of course, both entry points should implement a sort of resolver to call all other pages and console scripts but that's slightly out of scope of this article.
Helpful PHP commands and constants
There are may hepful commands and constants in PHP to ease the path interpolation. Some of them are:
__FILE__a constant that contains the full absolute path to the file which is currently executing.
__DIR__a constant that contains the path to a directory where lies the file which is currently executing (effectively it's just
__FILE__without the filename and the ending slash)
realpath()command will convert a relative path to an absolute one
getcwd()will give you the current directory