У меня есть суперкласс Abstract PHP, содержащий код, который должен знать, под каким подклассом он работает.
class Foo {
static function _get_class_name() {
return get_called_class();
//works in PHP 5.3.*, but not in PHP 5.2.*
}
static function other_code() {
//needs to know
echo self::_get_class_name();
}
}
class Bar extends Foo {
}
class FooBar extends Foo {
}
Bar::other_code(); // i need 'Bar'
FooBar::other_code(); // i need 'FooBar'
Это сработает, если я вызову функцию get_called_class ()
- однако этот код будет запускаться в PHP версии 5.2. *, Поэтому эта функция недоступна.
Есть несколько пользовательских PHP-реализаций get_called_class ()
, но все они полагаются на прохождение через debug_backtrack ()
, анализ имени файла и номера строки и запуск regex (поскольку кодировщик не знает, что PHP 5.2 имеет отражение), чтобы найти имя класса.Этот код должен быть запущен с php, т.е. не только из файла .php. (Это должно работать из оболочки php -a
или из оператора eval ()
.)
В идеале решение должно работать без необходимости добавления какого-либо кода в подклассы… Единственное возможное решение, которое я вижу, - это добавление следующего кода к каждому подклассу, что, очевидно, является отвратительным взломом:
class FooBar extends Foo {
static function _get_class_name() {
return 'FooBar';
}
}
РЕДАКТИРОВАТЬ: Подождите, похоже, это даже не работает. Это было бы моим последним средством. Может ли кто-нибудь придумать что-то похожее на это решение, которое дало бы мне необходимую функциональность. То есть, я готов принять решение, которое требует от меня добавления одной функции или переменной к каждому подклассу, сообщая ему, каково его имя класса. К сожалению, кажется, что вызов self :: _ get_class_name ()
из суперкласса вызывает реализацию родительского класса, даже если подкласс переопределил ее.
Я уже задавал подобный вопрос раньше, потому что я хотел, чтобы у родителя был фабричный метод, похожий на этот
public static function factory() {
return new __CLASS__;
}
Но он всегда возвращал родительский класс, а не унаследованный.
Мне сказали, что это невозможно без позднего статического связывания . Он был представлен в PHP 5.3. Вы можете прочитать документацию .
Это невозможно.
Понятие "вызываемый класс" было введено в PHP 5.3. Эта информация не отслеживалась в предыдущих версиях.
В качестве уродливого обходного пути вы могли бы использовать debug_backtrace
для просмотра стека вызовов, но это не эквивалентно. Например, в PHP 5.3 использование ClassName::method()
не перенаправляет статический вызов; у вас нет возможности сказать об этом с помощью debug_backtrace
. Кроме того, debug_backtrace
работает относительно медленно.