Resolving PHP Relative Paths Problems PDF Print E-mail
Wednesday, 17 March 2010 23:28

In this tutorial I will talk about the problem of using relative paths with the four following function: include(), include_once(), require() and require_once().



Problem:

When a PHP file includes another PHP file which itself includes yet another file -- all being in separate directories -- using relative paths to include them may raise a problem. PHP will often report that it is unable to find the third file, but why? Well the answer lies in the fact that when including files in PHP the interpreter tries to find the file in the current working directory. In other words, if you run the script in a directory called A and you include a script that is found in directory B, then the relative path will be resolved relative to A when executing script B. So, if the script inside directory B includes another file that is in a different directory, the path will be still calculated relative to A not relative to B as you might expect. This is a very important point to understand about the difference between PHP and other languages like C/C++.
To further clarify it, consider the following example taken from a post by "œvvo at geocities dot com" at http://bugs.php.net/bug.php?id=9673:

// File './test.php':
<?php
    require_once( 'include/a/a.inc' );
?>

// File './include/a/a.inc':
<?php
    require_once( '../b.inc' );
    echo 'a.inc ';
?>

// File './include/b.inc':
<?php
    echo 'b.inc ';
?>


Running 'test.php' fails with:

Fatal error: Failed opening required '../b.inc'
(include_path='.:/usr/local/lib/php') 
in /home/geeba/include/a/a.inc on line 2"

This is because the code looks for '../b.inc' relative to './' not relative to './include/a/'.


Solution:

In general, there are 2 solutions to this problem:

  1. Use $_SERVER["DOCUMENT_ROOT"]- We can use this variable to make all our includes relative to the server root directory, instead of the current working directory(script's directory). Then we would use something like this for all our includes:
    include($_SERVER["DOCUMENT_ROOT"] . "/dir/script_name.php");
    
  2. Use dir(__FILE__)- The __FILE__ constant contains the full path and filename of the script that it is used in. The function dir() removes the file name from the path, giving us the absolute path of the directory the file is in regardless of which script included it. Using this gives us the option of using relative paths just as we would with any other language, like C/C++. We would prefix all our relative path like this:
    include(dirname(__FILE__) . "/dir/script_name.php");
    

    You may also use basename together with function to find the included scripts name and not just the name of the currently executing script, like this:
    script_name = basename(__FILE__);
    

I personally prefer the second method over the first one, as it gives me more freedom and a better way to create a modular web application.

Note:  Remember that there is a difference between using a backslash "\" and a forward (normal) slash "/" under Unix based systems. If you are testing your application on a windows machine and you use these interchangeably, it will work fine. But once you try to move your script to a Unix server it will cause some problems. Backslashes ("\") are also used in PHP as in Unix, to indicate that the character that follows is a special character. Therefore, be careful not to use these in your path names.

This concludes this tutorial, I hope you enjoyed it and learned something useful. Thank you for reading, and if you have any feedback please post here or contact me directly.



Add this page to your favorite Social Bookmarking websites
 
Last Updated on Saturday, 18 June 2011 13:18
 
More articles :

» Deleting Multiple Database Tables – The Easy Way

In this short article I will describe how I went about deleting multiple database tables quickly without using the DROP DATABASE dbName statement. Feel free to skip right to the solution if you like.Background StoryAs part of changing one of our...

» Automatic Downloader in Python

This article will walk you through creating a python script to download all files on a web-page as fast as possible. The same script can then be used to download all sorts of content on the web, especially when combining the code with a web crawler....

» Script Tag Stripping Workaround in Joomla

If you ever tried inserting javascript into a Joomla article you may find it is a very difficult task; so, I went a head and made a plug-in to make this fast and easy. The reason why joomla makes it so difficult is because cross site scripting...

» Escaping HTML in Java

HTML uses some special characters to control how a page is displayed. These characters need to be escaped before placed on a page if they are to be displayed as part of the page content (and not just to control how the page appears). This is similar...

Comments  

 
0 #6 2011-11-28 10:08
I made up a quick solution for that purpose


$current_path = pathinfo($_SERV ER['SCRIPT_NAME'],PATHINFO_DIRN AME);
$current_host = pathinfo($_SERV ER['REMOTE_ADDR'],PATHINFO_BASE NAME);
$the_depth = substr_count( $current_path , "/" );




// PATH TO ROOT FOR INCLUDES TO ACCESS FROM ANYWHERE
if ($current_host=="127.0.0.1") $pathtoroot = str_repeat ( "../" , $the_depth-1 ); else $pathtoroot = str_repeat ( "../" , $the_depth );

then use this variable to refer to the root:
Quote
 
 
0 #5 2011-08-11 05:45
Great! Thanks a lot! U drive the web forward...
Quote
 
 
0 #4 Administrator 2011-06-18 13:26
@Shovan

No that will work, don't forgot the slash in the beginning however.

require_once(di rname(__FILE__) . '/../xyz.php');

The path will be relative to the file's directory rather than relative to the executing directory and that is normally what you want.
Quote
 
 
0 #3 2011-06-17 01:43
If I am using
require_once('../xyz.php');
what should be the correct statement using __DIR__ or dirname(__FILE_ _)

I guess require_once(di rname(__FILE_ _).'../xyz.php');
will not work.
Quote
 
 
+1 #2 2011-02-13 10:57
proved very useful for me... also i just found that __DIR__ magic constant also can be used in place of dirname(__FILE_ _)
Quote
 
 
0 #1 2010-06-06 16:43
Ahhh very useful thank you (:
Quote
 

Add comment


Security code
Refresh