Я, наконец, узнал о масштабах и контексте, и разнице между ними, но теперь у меня проблемы.
У меня есть статический метод в родительском классе, который наследуется дочерним классом. Когда я вызываю метод от дочернего элемента, я хочу, чтобы у родителя была возможность определить, какой дочерний элемент вызвал его.
Поздние статические привязки, верно? Здорово. Как это:
class Daddy {
public static function madSkillz() {
var_dump( static::class );
}
}
class Sonny extends Daddy {}
Sonny::madSkillz();
И в выводе я вижу:
string(5) "Sonny"
Ура, именно то, на что я надеялся! НО… Теперь давайте скажем, что я вызываю функцию из этого родительского статического метода. я могу использовать debug_backtrace
чтобы выяснить, что был вызван статический метод, но, к сожалению, я вижу декларирующий класс, а не область.
function GoToTheFair() {
var_dump( debug_backtrace() );
}
class Daddy {
public static function madSkillz() {
var_dump( static::class );
GoToTheFair();
}
}
class Sonny extends Daddy {}
Sonny::madSkillz();
Это печатает вывод:
string(5) "Sonny"array(2) {
[0]=>
array(4) {
["file"]=>
string(28) "/home/branja/Desktop/cry.php"["line"]=>
int(10)
["function"]=>
string(11) "GoToTheFair"["args"]=>
array(0) {
}
}
[1]=>
array(6) {
["file"]=>
string(28) "/home/branja/Desktop/cry.php"["line"]=>
int(16)
["function"]=>
string(9) "madSkillz"["class"]=>
string(5) "Daddy"["type"]=>
string(2) "::"["args"]=>
array(0) {
}
}
}
Я хочу быть в состоянии создать ReflectionMethod
объект в GoToTheFair()
и вызвать другие методы, но я должен быть уверен, что я использую правильную область, которая должен быть Sonny
не Daddy
,
Есть ли способ сделать это без прохождение static::class
в качестве аргумента GoToTheFair()
?
РЕДАКТИРОВАТЬ: Причина, по которой я не хочу использовать аргументный подход, состоит в том, что GoToTheFair()
функция библиотека, которую я кодирую и классы Daddy
а также Sonny
являются пользователем. Я не хочу, чтобы у них была свобода выбора своей сферы деятельности.
Кажется невозможным получить то, что вы хотите (в данном случае), потому что debug_backtrace()
использует постоянную __class__
для отображения имени класса.
В вашем контексте:
public static function madSkillz() {
var_dump( static::class ); // outputs : "Sonny"var_dump( __class__ ); // outputs : "Daddy"GoToTheFair();
}
Возможное решение 1:
Но вы можете получить правильный класс, если вызывающая сторона — это объект, а не статический метод. Вот пример использования объекта:
function GoToTheFair() {
$trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT) ;
$last = $trace[1] ;
var_dump(get_class($last['object'])) ;
}
class Daddy {
public function madSkillz() {
var_dump( static::class );
GoToTheFair();
}
}
class Sonny extends Daddy {}
(new Sonny)->madSkillz();
Будут ли выходы:
"Sonny""Sonny"
Возможное решение 2:
Вы могли бы использовать Синглтон.
function GoToTheFair() {
$trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT) ;
$last = $trace[1] ;
var_dump(get_class($last['object'])) ;
}
class Daddy {
private static $instance = null;
private function __construct() {}
public static function getInstance() {
$class = static::class ;
if (!isset(self::$instance))
self::$instance = new $class();
return self::$instance ;
}
public function madSkillz() {
var_dump( static::class );
GoToTheFair();
}
}
class Sonny extends Daddy {}
Sonny::getInstance()->madSkillz();
Будут ли выходы:
"Sonny""Sonny"
Других решений пока нет …