Is There Any Difference Between _Dir_ and Dirname(_File_) in 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.)

Difference Between getcwd() and dirname(__FILE__) ? Which should I use?

__FILE__ is a magic constant containing the full path to the file you are executing. If you are inside an include, its path will be the contents of __FILE__.

So with this setup:

/folder/random/foo.php

<?php
echo getcwd() . "\n";
echo dirname(__FILE__) . "\n" ;
echo "-------\n";
include 'bar/bar.php';

/folder/random/bar/bar.php

<?php
echo getcwd() . "\n";
echo dirname(__FILE__) . "\n";

You get this output:

/folder/random
/folder/random
-------
/folder/random
/folder/random/bar

So getcwd() returns the directory where you started executing, while dirname(__FILE__) is file-dependent.

On my webserver, getcwd() returns the location of the file that originally started executing. Using the CLI it is equal to what you would get if you executed pwd. This is supported by the documentation of the CLI SAPI and a comment on the getcwd manual page:

the CLI SAPI does - contrary to other SAPIs - NOT automatically change the current working directory to the one the started script resides in.

So like:

thom@griffin /home/thom $ echo "<?php echo getcwd() . '\n' ?>" >> test.php
thom@griffin /home/thom $ php test.php
/home/thom
thom@griffin /home/thom $ cd ..
thom@griffin /home $ php thom/test.php
/home

Of course, see also the manual at http://php.net/manual/en/function.getcwd.php

UPDATE: Since PHP 5.3.0 you can also use the magic constant __DIR__ which is equivalent to dirname(__FILE__).

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.

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

What does __FILE__ mean?

  1. The realpath() function gives you the file-system path, with any symbolic links and directory traversing (e.g. ../../) resolved. The dirname() function gives you just the directory, not the file within it.

  2. __FILE__ is a magic constant that gives you the filesystem path to the current .php file (the one that __FILE__ is in, not the one it's included by if it's an include.

  3. Sounds about right.

  4. This is to translate from Windows style (\) paths to Unix style (/).

dirname(__FILE__) VS setting global variable to directories

dirname(__FILE__) or __DIR__ are better than '/srv/www/htdocs/somwhere/' because they will keep working the day you'll move or rename your folders, or you migrate to another server or another OS.

Portability and flexibility are the main words here.

And globals are bad.

PHP how to go one level up on dirname(__FILE__)

For PHP < 5.3 use:

$upOne = realpath(dirname(__FILE__) . '/..');

In PHP 5.3 to 5.6 use:

$upOne = realpath(__DIR__ . '/..');

In PHP >= 7.0 use:

$upOne = dirname(__DIR__, 1);


Related Topics



Leave a reply



Submit