Obtener el nombre de ruta de una clase hereditaria en PHP
Pregunta
Estoy tratando de obtener el nombre de ruta absoluto de una clase de PHP que hereda de una superclase. Parece que debería ser simple. Creo que el siguiente código lo explica de la manera más sucinta posible:
// 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();
}
}
La razón por la que no quiero anular getAbsolutePathname()
es que habrá muchas clases que se extienden abstractfoo, en muchos lugares diferentes en el sistema de archivos (Foo es en realidad un módulo) y parece una violación de seco.
Solución
Bueno, podrías usar reflexión:
public function getAbsolutePathname() {
$reflector = new ReflectionObject($this);
return $reflector->getFilename();
}
No estoy seguro de si eso devolverá la ruta completa, o solo el nombre de archivo, pero no veo ningún otro método relevante, así que pruébalo ...
Otros consejos
Hasta donde yo sé, no hay una solución limpia para esto. Las constantes mágicas __FILE__
y __DIR__
se interpretan durante el análisis y no son dinámicos.
Lo que tiendo a hacer es
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__;
}
Podrías hackear algo con debug_backtrace
, pero eso todavía requiere que anule explícitamente la función principal en cada subcase.
Es mucho más fácil definir la función como return __FILE__;
en cada subcase. __FILE__
Siempre se reemplazará con el nombre del archivo en el que se encuentra, no hay forma de hacerlo hacerlo de otra manera.