tags:

views:

43

answers:

3

I'm trying to get the absolute pathname of a PHP class that inherits from a superclass. It seems like it should be simple. I think the code below explains it as succinctly as possible:

// myapp/classes/foo/bar/AbstractFoo.php
class AbstractFoo {

    public function getAbsolutePathname() {
        // this always returns the pathname of AbstractFoo.php
        return __FILE__;
    }

}


// myapp/classes/Foo.php
class Foo extends AbstractFoo {

    public function test() {
        // this returns the pathname of AbstractFoo.php, when what I
        // want is the pathname of Foo.php - WITHOUT having to override
        // getAbsolutePathname()
        return $this->getAbsolutePathname();
    }

}

The reason I don't want to override getAbsolutePathname() is that there are going to be a lot of classes that extend AbstractFoo, in potentially many different places on the filesystem (Foo is actually a module) and it seems like a violation of DRY.

A: 

You could hack something up with debug_backtrace, but that still requires you to explicitly override the parent function in each sub class.

It's far easier to define the function as return __FILE__; in each sub class. __FILE__ will always be replaced with the file name in which it is found, there is no way to make it do otherwise.

meagar
+1  A: 

As far as I know, there is no clean workaround for this. The magic constants __FILE__ and __DIR__ are interpreted during parsing, and are not dynamic.

What I tend to do is

class AbstractFoo {

    protected $path = null;

    public function getAbsolutePathname() {

        if ($this->path == null) 
              die ("You forgot to define a path in ".get_class($this)); 

        return $this->path;
    }

}


class Foo extends AbstractFoo {

  protected $path = __DIR__;

}
Pekka
+1 Replaces `function getAbsolutePathname() { return __DIR__; }` with `private $path = __DIR__;` in each sub-class, which is at least shorter
meagar
Doesn't `$path` need to be `protected` instead of `private`?
rojoca
@rojoca of course, you're right! Fixed, thanks.
Pekka
+2  A: 

Well, you could use reflection:

public function getAbsolutePathname() {
    $reflector = new ReflectionObject($this);
    return $reflector->getFilename();
}

I'm not sure if that will return the full path, or just the filename, but I don't see any other relevant methods, so give it a try...

ircmaxell
Thanks @Wrikken... That's what I get for typing without paying attention to what I'm writing...
ircmaxell
It does in fact return the full path. Perfect!
alexantd