5

I'm looking for the get_called_class() equivalent for __FILE__ ... Maybe something like get_included_file()?

I have a set of classes which would like to know what directory they exist in. Something like this:

<?php

class A {

    protected $baseDir;

    public function __construct() {
        $this->baseDir = dirname(__FILE__);
    }

    public function getBaseDir() {
        return $this->baseDir;
    }
}

?>

And in some other file, in some other folder...

<?php

class B extends A {
    // ...
}

class C extends B {
    // ...
}

$a = new A;
echo $a->getBaseDir();

$b = new B;
echo $b->getBaseDir();

$c = new C;
echo $c->getBaseDir();

// Annnd... all three return the same base directory.

?>

Now, I could do something ghetto, like adding $this->baseDir = dirname(__FILE__) to each and every extending class, but that seems a bit... ghetto. After all, we're talking about PHP 5.3, right? Isn't this supposed to be the future?

Is there another way to get the path to the file where a class was declared?

bobthecow
  • 5,047
  • 25
  • 27
  • I think the only way is the 'ghetto', but why are you doing this, perhaps there is another approach to the problem? – Josiah Apr 27 '10 at 05:05
  • @Josiah This is for the view layer of an application. Each view object (usually) consists of a view class and a view template file. In the example above A, B and C are view classes. Each would have, in their parent directory, a matching template file. It would be great to define said directory once, though, instead of every time... – bobthecow Apr 27 '10 at 05:30

5 Answers5

5

ReflectionClass::getFileName

olamedia
  • 188
  • 2
  • 6
3

Have you tried assigning it as a static member of the class?

<?php
class Blah extends A {
    protected static $filename = __FILE__;
}

(Untested, and statics plus class inheritance becomes very fun...)

Charles
  • 50,943
  • 13
  • 104
  • 142
1

what if you don't use __FILE__ but a separate variable and set the variable to __FILE__ in each class

class A {

    protected static $baseDir;
    protected $filename = __FILE__; // put this in every file

    public function __construct() {

    }

    public function getBaseDir() {
        return dirname($this->filename) . '<br>'; // use $filename instead of __FILE__
    }   

}

require('bdir/b.php');
require('cdir/c.php');

class B extends A {
    protected $filename = __FILE__; // put this in every file
}

$a = new A;
echo $a->getBaseDir();

$b = new B;
echo $b->getBaseDir();

$c = new C;
echo $c->getBaseDir();

you still have to redeclare the property in each class, but not the method

NikiC
  • 100,734
  • 37
  • 191
  • 225
Galen
  • 29,976
  • 9
  • 71
  • 89
  • Yeah, I was worried that it would come down to an answer like this. Note that if you can require PHP 5.3, you can store the equivalent of dirname(\_\_FILE\_\_) by declaring this in every extending class: protected $dirName = __DIR__; – bobthecow Apr 28 '10 at 23:43
0

Tested:

    protected static $filename = __FILE__; 
    static::$filename 

Doesn't work.

It looks like the constant is registered when the class is loaded which is not "late".

Not sure it was possible before, but what was best for me today is using reflection :

    $basePath = new \ReflectionObject($this);
    $dir = dirname($basePath->getFileName());
cyqui
  • 97
  • 2
  • 10
  • Almost there! You can also avoid `$this` (in case of static methods) by using late-static-binding + ReflectionClass, eg `(new \ReflectionClass(static::class))->getFileName()`. – Christian Jan 09 '21 at 23:37
0

You could use debug_backtrace(). You probably don't want to, though.

Tgr
  • 27,442
  • 12
  • 81
  • 118