Как получить путь производного класса от унаследованного метода?
Как получить путь к текущему классу из унаследованного метода?
У меня есть следующее:
<?php // file: /parentDir/class.php
class Parent {
protected function getDir() {
return dirname(__FILE__);
}
}
?>
и
<?php // file: /childDir/class.php
class Child extends Parent {
public function __construct() {
echo $this->getDir();
}
}
$tmp = new Child(); // output: '/parentDir'
?>
Константа __FILE__
всегда указывает на исходный файл файла, в котором он находится, независимо от наследования.
Я хотел бы получить имя пути для производного класса.
Есть ли элегантный способ сделать это?
Я мог бы что-то сделать по строкам $this->getDir(__FILE__);
, но это означало бы, что я должен повторять себя довольно часто. Я ищу метод, который по возможности ставит всю логику в родительский класс.
Update:
Принятое решение (Palantir):
<?php // file: /parentDir/class.php
class Parent {
protected function getDir() {
$reflector = new ReflectionClass(get_class($this));
return dirname($reflector->getFileName());
}
}
?>
Ответы
Ответ 1
Используя ReflectionClass::getFileName
с этим, вы получите dirname, для которого определен класс Child
.
$reflector = new ReflectionClass("Child");
$fn = $reflector->getFileName();
return dirname($fn);
Вы можете получить имя класса объекта с помощью get_class()
:)
Ответ 2
Да. На основе ответа Палантира:
class Parent {
protected function getDir() {
$rc = new ReflectionClass(get_class($this));
return dirname($rc->getFileName());
}
}
Ответ 3
Не забывайте, что с 5.5 вы можете использовать ключевое слово class
для разрешения имен классов, что было бы намного быстрее, чем вызов get_class($this)
. Принятое решение будет выглядеть так:
protected function getDir() {
return dirname((new ReflectionClass(static::class))->getFileName());
}
Ответ 4
Если вы используете Composer для автозагрузки, вы можете получить каталог без отражения.
$autoloader = require 'project_root/vendor/autoload.php';
// Use get_called_class() for PHP 5.3 and 5.4
$file = $autoloader->findFile(static::class);
$directory = dirname($file);
Ответ 5
Вы также можете передать каталог как конструктор arg. Не очень элегантно, но, по крайней мере, вам не нужно работать с отражением или композитором.
Родитель:
<?php // file: /parentDir/class.php
class Parent {
private $directory;
public function __construct($directory) {
$this->directory = $directory;
}
protected function getDir() {
return $this->directory;
}
}
?>
Ребенок:
<?php // file: /childDir/class.php
class Child extends Parent {
public function __construct() {
parent::__construct(realpath(__DIR__));
echo $this->getDir();
}
}
?>
Ответ 6
<?php // file: /parentDir/class.php
class Parent {
const FILE = __FILE__;
protected function getDir() {
return dirname($this::FILE);
}
}
?>
<?php // file: /childDir/class.php
class Child extends Parent {
const FILE = __FILE__;
public function __construct() {
echo $this->getDir();
}
}
$tmp = new Child(); // output: '/childDir'
?>
Пожалуйста, помните, что если вам нужно получить каталог, напрямую используйте __DIR__
.