PHP include paths

One of the nice things about PHP is that it is easy to write one common file for things like headers and footers and then include that file in every page that you publish. For simple sites, it is easy, you just include a line like this in as the first line your code.


<?php
require_once('header.inc'); ?>

where the file is something like this:

<!doctype html>
<html lang="en-US">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="copyright" content="Copyright ©<?php echo $now; ?> Well Golly.com" />
  <meta name="rating" content="general" />
  <meta name="robots" content="all" />
  <meta name="description" lang="en" content="<?php echo $meta_description; ?>"/>
  <meta name="keywords" content="<?php echo $meta_keywords; ?>" />
  <meta name="robots" lang="en" content="index follow" />

    <link rel="icon" type="image/png" href="./common_images/favicon.png" />
    <link rel="apple-touch-icon" href="./common_images/apple-touch-icon.png"/>
    <link rel="stylesheet" href="/css/pure-min.css">
    <title><?php echo $page_title; ?></title>
</head>

Once you have the basic file in place, you can start embellishing it. Note that I refer to several PHP variables. If you examine the source for this page, you see that it is copied literally into the HTML source and a few variables that I previously defined take on their values. These are defined in a file that I call set_variables.inc.


<?php
    $day = date("Y-m-d",strtotime("now"));
    $today = date("Y-m-d");
    $nowDate = date('Y');    // Used for copyright notices in the header tag and in the footer.

  // Here is where you provide information about your site.
  $site_name = "Well Golly";
  $site_shortName = "Well Golly";
  $site_URL = "https://Well Golly.com";

  $copyright_text = "© Copyright $nowDate $site_name";
  $footer_text = "&copy; Copyright $nowDate <a href=\"{$site_URL}\">$site_name</a> $site_address&nbsp;&nbsp;$site_phone";

  $keywords = "$site_name"; // Separate terms with commas
  $description = "$site_name web-based exercises.";

  $meta_description = 'Well Golly Exercises.';
    $meta_keywords = 'products, apps, software';

  $page_title = "$site_name Exercises";

?>

Note that this file starts with because none of the information on the page is HTML. This file defines variables that I use in other files to generate HTML.

One thing that is confusing at first is how PHP finds the included files. If you just use the file name in the call, then PHP looks in the current directory for the file. PHP uses Unix conventions, so if you are in a subdirectory and want to call a file one level above, you would preface the file name with ../ e.g.


<?php
require_once('../header.inc'); ?>

Likewise, two levels up is ../../ and two levels up then down a level is ../../directory. This can get confusing after a while so what most people do is create a directory in the document root and put include files that are used throughout the site in it. Here’s an example of my include.php file for a site.


agreement.inc
check_login.inc
footer_menu.inc
footer.inc
header_logo.inc
header_menu.inc
header.inc
login_validation.inc
set_variables.inc
signup_confirmation.inc
signup_form.inc
signup_updateDB.inc
signup_validation.inc
timeZones.inc

Remembering to put the correct number of ../s can be tiresome so what I do is define a search path and put it in my php.ini file. I don’t remember precisely what it looks like, but this line from my /var/log/php_error.log file tells me where PHP was looking for a file that it can’t find.


 PHP Fatal error:  require_once(): Failed opening required './include.php/header_menu.inc' (include_path='.:/usr/share/php5:/usr/share/php:./include.php:..:../include.php:../../include.php:../../../include.php')

I basically says to look first in the current directory . , then in the PHP provided directories, then in the next level up, etc. If you want to override the search path you can just specify where PHP should look for the file. For example, in the page where users interact with your app, you may not want all of the normal branding and menu choices. Create a simple header file and access it directly by specifying the path.

<?php
require_once('./header.inc'); ?>

You can do the same thing for CSS and javascript. I do this for all of my apps since there is some common javascript but much of it is specific to an app and I don”t want the code to get confused because I used a function name that has a different input and output in other apps. Plus there is less code being downloaded so the page loads faster.

Where it gets tricky is when you start thinking that PHP starts looking in the document root for files and images when in fact it starts looking in the root of the server as defined in your Apache2 conf file. In my case it is /srv/www.

So if you want to include an image in your logo, you might put it in /common_images in the document root. However, if you call it using <img src='/common_images/logo.png' alt=logo' /> PHP won’t find it because it will be looking in /srv/www//common_images/logo.png. Remove the first slash and you are good to go—if you are calling the images from the same level as common_images. You could add the path to your php.ini file, but I have a bunch of folders that I use where I would have to do that. An easier way is to use PHP server variables. In the example below, I have already defined the $site_URL in my set_varialbles.inc file and use a built-in PHP function, explode, to get the filename of the directory where my common_images directory is located. So no matter how far down the directory tree I am, I can still get the location where the logo is located—https://beta.wellgolly.com/exercises/common_images.


<div id="header" class="pure-g">
  <div class="pure-u-1 pure-u-lg-1-2">
    <a href="<?php echo $site_URL ?>">
    <?php 
      $curRoot = explode("/", $_SERVER['REQUEST_URI']);
    ?>
      <img class="pure-img-responsive" src="<?php echo "{$site_URL}/{$curRoot[1]}" ?>/common_images/wg_header.png" alt="Header">
    </a>
  </div>
</div>

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.