1

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?

Rob W
  • 341,306
  • 83
  • 791
  • 678
Nik
  • 2,424
  • 3
  • 18
  • 16
  • "\`" is for inline code. For [code blocks](http://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks), indent each line an extra four spaces. The "{}" button in the editor toolbar does this for you. "\*", "-" or "+" can be used for lists. Examine my edits to see how. Click the orange question mark in the editor toolbar for more information and tips on formatting. – outis Sep 26 '11 at 23:31
  • Did you mean to use function notation (parentheses) instead of array indexing (square brackets) when referring to the `$_SERVER` variable? If so, that may be why you couldn't get them to work. – outis Sep 26 '11 at 23:35

2 Answers2

3

Use set_include_path(), it'll make your life much easier.

outis
  • 75,655
  • 22
  • 151
  • 221
Scott
  • 1,477
  • 12
  • 13
  • Works. I just need to find a way to have it dynamically set the include path based on the directory root. – Nik Oct 31 '10 at 05:19
  • 1
    You would use a bootstrapping procedure, your first include for your page should always be your bootstrap.php file that sets your path. – Scott Oct 31 '10 at 05:20
1

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.)

drewm
  • 2,003
  • 1
  • 16
  • 22
kijin
  • 8,702
  • 2
  • 26
  • 32
  • Sorry, I was working on recursion at the same time as this issue and it's just one big headache. – Nik Oct 31 '10 at 04:59
  • Relative paths have their uses. And "NEVER use relative paths" is a bit hypocritical, considering you're doing the exact same thing (in disguise even!) with `dirname(__FILE__)`. – cHao Oct 31 '10 at 07:10