Why would I use dirname(__FILE__) in an include or include_once statement?

I have seen this:

<?php
  include( dirname(__FILE__) . DIRECTORY_SEPARATOR . 'my_file.php');
?>

Why would I ever need to do this? Why would I go to the trouble of getting the dirname and then concatenating that with a directory separator, and a new filename?

Is the code above not equivalent to this:

<?php
  include( 'my_file.php' );
?>

??

The PHP doc says,

Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include() will finally check in the calling script's own directory and the current working directory before failing. The include() construct will emit a warning if it cannot find a file; this is different behavior from require(), which will emit a fatal error.


Let's say I have a (fake) directory structure like:

.../root/
        /app
            bootstrap.php
        /scripts
            something/
                somescript.php
        /public
            index.php

Now assume that bootstrap.php has some code included for setting up database connections or some other kind of boostrapping stuff.

Assume you want to include a file in boostrap.php's folder called init.php. Now, to avoid scanning the entire include path with include 'init.php', you could use include './init.php'.

There's a problem though. That ./ will be relative to the script that included bootstrap.php, not bootstrap.php. (Technically speaking, it will be relative to the working directory.)

dirname(__FILE__) allows you to get an absolute path (and thus avoid an include path search) without relying on the working directory being the directory in which bootstrap.php resides.

(Note: since PHP 5.3, you can use __DIR__ in place of dirname(__FILE__).)

Now, why not just use include 'init.php';?

As odd as it is at first though, . is not guaranteed to be in the include path. Sometimes to avoid useless stat()'s people remove it from the include path when they are rarely include files in the same directory (why search the current directory when you know includes are never going to be there?).

Note: About half of this answer is address in a rather old post: What's better of require(dirname(__FILE__).'/'.'myParent.php') than just require('myParent.php')?


I might have even a simpler explanation to this question compared to the accepted answer so I'm going to give it a go: Assume this is the structure of the files and directories of a project:

Project root directory:
                       file1.php
                       file3.php
                       dir1/
                            file2.php

(dir1 is a directory and file2.php is inside it)

And this is the content of each of the three files above:

//file1.php:
<?php include "dir1/file2.php"

//file2.php:
<?php include "../file3.php"

//file3.php:
<?php echo "Hello, Test!";

Now run file1.php and try to guess what should happen. You might expect to see "Hello, Test!", however, it won't be shown! What you'll get instead will be an error indicating that the file you have requested(file3.php) does not exist!

The reason is that, inside file1.php when you include file2.php, the content of it is getting copied and then pasted back directly into file1.php which is inside the root directory, thus this part "../file3.php" runs from the root directory and thus goes one directory up the root! (and obviously it won't find the file3.php).

Now, what should we do ?!

Relative paths of course have the problem above, so we have to use absolute paths. However, absolute paths have also one problem. If you (for example) copy the root folder (containing your whole project) and paste it in anywhere else on your computer, the paths will be invalid from that point on! And that'll be a REAL MESS!

So we kind of need paths that are both absolute and dynamic(Each file dynamically finds the absolute path of itself wherever we place it)!

The way we do that is by getting help from PHP, and dirname() is the function to go for, which gives the absolute path to the directory in which a file exists in. And each file name could also be easily accessed using the __FILE__ constant. So dirname(__FILE__) would easily give you the absolute (while dynamic!) path to the file we're typing in the above code. Now move your whole project to a new place, or even a new system, and tada! it works!

So now if we turn the project above to this:

//file1.php:
<?php include(dirname(__FILE__)."/dir1/file2.php");

//file2.php:
<?php include(dirname(__FILE__)."/../file3.php");

//file3.php:
<?php echo "Hello, Test!";

if you run it, you'll see the almighty Hello, Test!! (hopefully, if you've not done anything else wrong).

It's also worth mentioning that from PHP5, a nicer way(with regards to readability and preventing eye boilage!) has been provided by PHP as well which is the constant __DIR__ which does exactly the same thing as dirname(__FILE__)!

Hope that helps.