Why Would I Use Dirname(_File_) in an Include or Include_Once Statement

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

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')?

Is there any difference between __DIR__ and dirname(__FILE__) in PHP?

Their result is exactly the same ; so, no difference on that.


For example, the two following lines :

var_dump(dirname(__FILE__));
var_dump(__DIR__);

Will both give the same output :

string '/home/squale/developpement/tests/temp' (length=37)


But, there are at least two differences :

  • __DIR__ only exists with PHP >= 5.3
    • which is why dirname(__FILE__) is more widely used
  • __DIR__ is evaluated at compile-time, while dirname(__FILE__) means a function-call and is evaluated at execution-time

    • so, __DIR__ is (or, should be) faster.


As, as a reference, see the Magic constants section of the manual (quoting) :

__DIR__ : The directory of the file.

If used inside an include, the
directory of the included file is
returned.
This is equivalent to
dirname(__FILE__).
This
directory name does not have a
trailing slash unless it is the root
directory.
(Added in PHP 5.3.0.)

What's better of require(dirname(__FILE__).'/'.'myParent.php') than just require('myParent.php')?

PHP needs to know the absolute path to the file. dirname(__FILE__).'/myParent.php' already is the absolute path but 'myParent.php' requires a lookup using the given paths in include_path to get an absolute path and find the file. A better choice would be './myParent.php':

However, it is more efficient to explicitly use include './file' than having PHP always check the current directory for every include.

what is the purpose of require_once dirname(__FILE__) ...?

Yes, you are right - dirname(__FILE__) ensures that the require_once function uses an absolute rather than relative path.

The __FILE__ constant represents the running script. It will return the full path and file name of the running script.

For example, if a script called database.init.php which is included from anywhere on the filesystem wants to include the script database.class.php, which lays in the same directory, you can use:

require_once dirname(__FILE__) . '/database.class.php'; 

Wordpress - Include_once root files

If you have a standard wp-config.php file, ABSPATH should be defined. This means you should be able to use:

include_once(ABSPATH . 'includes/db_connect.php');

Read more in this related answer.

PHP dirname(__FILE__) v/s ./

When you use ./ you're looking in the current working directory which might change. dirname(__FILE__) on the other hand won't change.

If you for instance change the working directory (using chdir('/') or similar) before the require, your first example will succeed whereas your second will fail.

Excerpt from another answer:

However, it is more efficient to explicitly use include './file' than having PHP always check the current directory for every include.

So if you know you're not going to be changing directory, ./ will be faster.

PHP will include a file relative to a calling script, but not if the include path contains ../

PHP's a bit odd in how it looks for files. If you include a file whose name starts with a slash or a dot, PHP ignores the include_path entirely. If a dot, it assumes the name is relative to the script that kicked off everything (ie: the one the web server decided to run).

If you want to specify a path relative to the included script and not the startup one, what you really want is an absolute include that specifies the full name of the file. That's easy to do with the __FILE__ and __DIR__ constants, which reflect the name and directory of the currently running script.

include __DIR__ . '/../dirB/c.php';

If you like, you can also set the include_path config setting to include the root of the app, and just specify all filenames relative to that.



Related Topics



Leave a reply



Submit