Search code examples
phprecursionrequirerequire-once

How do I require files in other directory branches?


When I try to use require or require_once, it will work fine if the file to be required is in the same subdirectory, but the moment it sees a file outside of their subdirectory, it generates a fatal error. Here is basically what the file tree looks like:

* main.php
+ login/
   * login.php
+ includes/
   * session.php

...so basically, if I were to have main.php require login/login.php, it's fine, but if I try to do directory traversal for login.php to require includes/session.php, it fails, resulting in the error:

PHP Fatal error: require_once(): Failed opening required [...]

The code for this concept would be:

require('login/login.php') #works fine (main.php)
require('../includes/session.php') #quits (login.php)

I have tried using $_SERVER('DOCUMENT_ROOT'), $_SERVER('SERVER_ADDR'), dir(_FILE_), and chdir(../). I remember working on a project a few months back that I solved this problem on, it was a simple function that traversed file paths, but I can't find it anymore. Any ideas?


Solution

  • This ain't recursion, it's just plain old directory traversal.

    NEVER use relative paths for include/require. You never know from which directory your script was invoked, so there's always a possibility that you'll be in the wrong working directory. This is just a recipe for headaches.

    ALWAYS use dirname(__FILE__) to get the absolute path of the directory where the current file is located. If you're on PHP 5.3, you can just do __DIR__. (Notice two underscores front and back.)

    require dirname(__FILE__).'/../includes/session.php';
    

    (By the way, you don't need parentheses around include/require because it's a language construct, not a function.)

    Using absolute paths might also have better performance because PHP doesn't need to look into each and every directory in include_path. (But this only applies if you have several directories in your include_path.)