5

Often I see this type of code __DIR__.'/../Resources/config'. But why is the point, am I wrong that is it the same that typing ../Resources/config' ?

ricko zoe
  • 496
  • 1
  • 6
  • 19

2 Answers2

6

Because in many cases the relative path won't work, for example when the script is run from some other folder. Using __ DIR __ converts the relative path into absolute path, leaving no space for any confusion.

For your question lets suppose this hierarchy,

/
test/
test/script.php
test/Resource/config
another/

Now script.php contains this path, you run the script from the directory test so the relative path is resolved to test/Resource/config. Its what you wanted.

But if you run the script from say another, then the path will be resolved to another/Resource/config which is not right.

If you have used __DIR__, it always get resolved into the path of the script that it is used in. So the relative path would have become /test/Resource/config

Now no matter from where you run this script, since the path is absolute, it won't be resolved relatively and will remain the same.

Akshendra Pratap
  • 2,002
  • 1
  • 12
  • 25
6

No, it's not always the same thing. __DIR__ is the directory of the file, not the current working directory. This code is essentially a dynamically-generated absolute path.

Write this into ~/foo/script.php:

<?php
// Ta, Sven
//  https://php.net/manual/en/function.realpath.php#84012
function get_absolute_path($path) {
    $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path);
    $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen');
    $absolutes = array();
    foreach ($parts as $part) {
        if ('.' == $part) continue;
        if ('..' == $part) {
            array_pop($absolutes);
        } else {
            $absolutes[] = $part;
        }
    }
    return '/' . implode(DIRECTORY_SEPARATOR, $absolutes);
}

$p = __DIR__ . '/../bar';
echo $p . "\n" . get_absolute_path($p) . "\n";
?>

Now:

$ cd ~/foo
$ php script.php
/home/me/foo/../bar
/home/me/bar

$ cd ~/
$ php foo/script.php
/home/me/foo/../bar
/home/me/bar

But if we got rid of __DIR__:

$ cd ~/foo
$ php script.php
../bar
/home/me/bar

$ cd ~/
$ php foo/script.php
../bar
/home/bar

See ... that last path is incorrect.

If we were using these paths anywhere, they'd be broken without __DIR__.

Whenever you write a script, you should ensure that it is safe to execute it from some directory other than the one in which it lives!

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Thanks but can you give more uses cases ? – ricko zoe Oct 22 '15 at 17:50
  • 1
    It's hard to see how this could be any clearer, or what any other examples would show – Rob G Oct 22 '15 at 17:57
  • is that the only reason you use __DIR__? In case the the script is executed from other directories? is there other reasons why you would use __DIR__? – Soujirou Oct 22 '15 at 18:05
  • @Soujirou I think in case of classes as well – Akshendra Pratap Oct 22 '15 at 18:20
  • @Soujirou: Since `__DIR__` (not "**DIR**") gives you the script's directory, it stands to reason that whether you use it or not will affect things that relate to directories. Really, this seems like more than enough of a reason. Large PHP projects have files `include`d from different directories all over the place. – Lightness Races in Orbit Oct 22 '15 at 18:44
  • @LightnessRacesinOrbit, http://stackoverflow.com/questions/11604445/php-absolute-path-to-root, I was talking about this – Akshendra Pratap Oct 22 '15 at 18:57
  • @AkshendraPratap: What does that have to do with classes? – Lightness Races in Orbit Oct 22 '15 at 19:21
  • @LightnessRacesinOrbit, I am sorry if I am not clear. Again what I meant is that if you access a file inside a class using relative path, then this path is being resolved from the script where the object of this class is being instantiated. That's the problem is the linked question isn't it? – Akshendra Pratap Oct 22 '15 at 19:33
  • @AkshendraPratap: No, it has nothing to do with classes. You're just extending the original problem: relative directory paths when evaluated from a different directory. The same happens with code in a non-class function. And with code that's not in a function at all. The fact that you can put that code into a class method is irrelevant. – Lightness Races in Orbit Oct 22 '15 at 20:00