PHP - Including Files From Different Directories


When developing this site, I ran into an issue with the include function in PHP. The include function allows you to insert the contents of one file into a PHP file. This is helpful for reusing chunks of code. For example, each page on this site reuses the same code to put the logo in the top left corner of the header. Below is a subset of the file structure for this site. At the top level, or the root level, we have index.php which is the Home page. We also have directories for our php files and our image files. In the file structure below, logo.php is included by index.php, articles.php, breaking_things.php and php_include.php.




Originally, I designed logo.php as shown below. Notice that there is a relative path on line 2 and line 3. If you check these paths against the file structure above, you can see that they are correct. The problem I had is that anytime I included logo.php into index.php, the logo would not show up. This is because, in PHP, when you include one file, say file A into another file, say file B, it's as if the contents of A are copied and pasted into B. Since, index.php is in a different directory than logo.php, the relative paths from logo.php are now incorrect when it's included in index.php.


<div id="bannerLogoDiv" class="bannerLogoDiv">
<a id="logoLink" class="plain" href="../../index.php" >
<img id="logoImg" src="../../img/thepaulfoleylogo.bmp" width="75px" height="100px" border="0"/>
</a>
</div>


To solve this problem I added a PHP variable called $toRoot in every file that included another file. The variable $toRoot is a relative path to the root directory, in this case the top level directory called thepaulfoley. So, since index.php is in the root directory, $toRoot would be an empty string. In articles.php, breaking_things.php and php_include.php, $toRoot would equal "../../". Then in any file that was included by another file, all relative paths were based on the $toRoot variable. So, logo.php was rewritten as shown below. The changes made are shown in red. You can see that now the relative paths are based on the $toRoot variable.


<div id="bannerLogoDiv" class="bannerLogoDiv">
<a id="logoLink" class="plain" href=<?php echo $toRoot."index.php" ?> >
<img id="logoImg" src=<?php echo $toRoot."img/thepaulfoleylogo.bmp" ?> width="75px" height="100px" border="0"/>
</a>
</div>


To summarize, if you are including files from different directories you can eliminate problems with relative paths by doing the following. In each file that includes another file, add a variable $toRoot whose value is the relative path to the root directory. Then, in each file that is included by another file, base all relative paths on the $toRoot variable. Finally, you may be wondering why I didn't just avoid these troubles by using absolute paths instead of relative paths. The reason is that I host this site on a third-party server. I have a working copy of the code on my local machine. When I make changes, I make them locally, test them and then upload them to the server. By using relative paths, I don't have to make any changes to the code when going from my local machine to the server or vice-versa.


Copyright 2010 Paul Foley. All rights reserved.