How does include path resolution work in require_once?

jrharshath picture jrharshath · Dec 29, 2009 · Viewed 43.3k times · Source

I was writing an web app in PHP, when I encountered a strange situation. To illustrate my problem, consider a web app of this structure:

/
    index.php
    f1/
        f1.php
    f2/
        f2.php

Contents of these files:

index.php:

<?php require_once("f1/f1.php"); ?>

f1.php:

<?php require_once("../f2/f2.php"); ?>

f2.php: blank

now when I try to open index.php in my browser I get this error:

Warning: require_once(../f2/f2.php) [function.require-once]: 
failed to open stream: No such file or directory in /var/www/reqtest/f1/f1.php on line 2
Fatal error: require_once() [function.require]: 
Failed opening required '../f2/f2.php' (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/reqtest/f1/f1.php on line 2

Is there something obvious I'm missing? how do include paths work in PHP?


Before I asked this question, I attempted to experiment and find out. I set up another test, like so:

/
    index.php
    f1/
        f1.php
        f2.php

index.php:

<?php require_once("f1/f1.php"); ?>

f1.php:

<?php require_once("f2.php"); ?>

f2.php: blank

To my surprise (and utter confusion), this worked out fine!

So, what is the secret behind the path resolution?

PS I saw this question, but it still does not answer the second case that I've stated here.

Answer

Karsten picture Karsten · Dec 29, 2009

If you include another file, the working directory remains where the including file is.

Your examples are working as intended.

Edit: The second example works because . (actual directory) is in your include path (see your error message).

Edit2: In your second example, the key point of your interest is this line:

<?php require_once("f2.php"); ?>

At first it will look in the current working dir (/var/www/req_path_test), but does not find f2.php.

As fallback, it will try to find f2.php in your include_path ('.:/usr/share/php:/usr/share/pear'), starting with '.' (which is relative to the actual file, not the including one).

So './f2.php' works and the require does not fail.