отражение — вы можете разрешить поздние статические привязки вне области видимости в PHP?

Я, наконец, узнал о масштабах и контексте, и разнице между ними, но теперь у меня проблемы.

У меня есть статический метод в родительском классе, который наследуется дочерним классом. Когда я вызываю метод от дочернего элемента, я хочу, чтобы у родителя была возможность определить, какой дочерний элемент вызвал его.

Поздние статические привязки, верно? Здорово. Как это:

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 являются пользователем. Я не хочу, чтобы у них была свобода выбора своей сферы деятельности.

2

Решение

Кажется невозможным получить то, что вы хотите (в данном случае), потому что 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"
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]