Есть ли способ определить целевой класс в статических методах?
Вопрос
Ниже приведен пример иерархии классов и кода.Я ищу способ определить, имел ли «ChildClass1» или «ChildClass2» статический метод whoAmI(), вызванный им, без его повторной реализации в каждом дочернем классе.
<?php
abstract class ParentClass {
public static function whoAmI () {
// NOT correct, always gives 'ParentClass'
$class = __CLASS__;
// NOT correct, always gives 'ParentClass'.
// Also very round-about and likely slow.
$trace = debug_backtrace();
$class = $trace[0]['class'];
return $class;
}
}
class ChildClass1 extends ParentClass {
}
class ChildClass2 extends ParentClass {
}
// Shows 'ParentClass'
// Want to show 'ChildClass1'
print ChildClass1::whoAmI();
print "\n";
// Shows 'ParentClass'
// Want to show 'ChildClass2'
print ChildClass2::whoAmI();
print "\n";
Решение 3
Теперь, когда PHP 5.3 широко доступен, я хотел дать краткий ответ на этот вопрос, чтобы отразить новые доступные методы.
Как упоминалось в других ответах, PHP 5.3 представил Позднее статическое связывание через новый static
ключевое слово.Так же новый get_called_class()
также доступна функция, которую можно использовать только внутри метода класса (экземплярного или статического).
Для определения класса, как было задано в этом вопросе, get_called_class()
функция подходит:
<?php
abstract class ParentClass {
public static function whoAmI () {
return get_called_class();
}
}
class ChildClass1 extends ParentClass {
}
class ChildClass2 extends ParentClass {
}
// Shows 'ChildClass1'
print ChildClass1::whoAmI();
print "\n";
// Shows 'ChildClass2'
print ChildClass2::whoAmI();
print "\n";
А добавленные пользователем заметки для get_called_class()
включите несколько примеров реализаций, которые должны работать и в PHP 5.2, используя debug_backtrace()
.
Другие советы
Я считаю, что вы имеете в виду известную ошибку PHP.В PHP 5.3 эта проблема решена с помощью новой функции позднего статического связывания.
http://www.colder.ch/news/08-24-2007/28/late-static-bindings-expl.html
Идентификация класса часто является симптомом недостаточно понятного полиморфизма.
Клиентам ChildClass1 и ChildClass2 не нужно различать их.
Нет места, где любой класс мог бы спрашивать о someObject.whoAmI()
.
Всякий раз, когда у вас есть желание написать if someObject.whoAmI() == 'ChildClass1' { do X(someObject) }
вам действительно следует добавить X()
метод для ParentClass с различными реализациями в различных дочерних классах.
Этот вид «идентификации типов во время выполнения» почти всегда можно заменить правильно полиморфными проектами классов.
Начиная с PHP 5.3 это будет возможно с использованием статическое ключевое слово, но пока это невозможно.
Нет.Подождите PHP 5.3.