Мне нужно иметь возможность использовать статическую переменную, заданную в классе, которая расширяет базовый класс … из базового класса.
Учти это:
class Animal { public static $color = 'black'; public static function get_color() { return self::$color; } } class Dog extends Animal { public static $color = 'brown'; } echo Animal::get_color(); // prints 'black' echo Dog::get_color(); // also prints 'black'
Это прекрасно работает в PHP 5.3.x ( Dog::get_color()
печатает «коричневый»), так как имеет позднюю статическую привязку. Но мой производственный сервер работает с PHP 5.2.11, поэтому мне нужно адаптировать мой скрипт.
Есть несколько довольно обходной путь для решения этой проблемы?
Ура!
Кристоффер
EDIT: Цель
Как отмечено ниже, это очень упрощенный пример того, что я пытаюсь выполнить. Если я предоставил вам два варианта, которые я использовал для решения моей проблемы (и сама проблема), у кого-то может быть другое решение, чем у меня …
Я создал базовую модель базы данных, которая содержит такие функции, как «find», «find_by» и «find_all» (все статические).
В PHP 5.3 существует функция, называемая get_called_class()
которую я использую в настоящее время для определения имени вызываемого класса, а затем используйте ее для сопоставления с соответствующей таблицей базы данных. User
Ex class User
укажет на users
.
get_called_class()
не существует в PHP 5.2.x, и реализованные get_called_class()
реализации hack очень ненадежны. Затем я обратился к этому варианту использования статической переменной во всех классах моделей, которые содержат имя класса.
К сожалению, перед PHP 5.3 невозможно смоделировать позднюю статическую привязку. Единственный способ заставить наследование работать так, как вы намереваетесь, – это те переменные и методы экземпляра.
Я столкнулся с этой проблемой при подклассификации чего-то в Zend Framework. Моя решимость заключалась в том, что в чистой статической земле у вас есть только один вариант … Переопределите функцию в классе наследования:
class Animal { public static $color = 'black'; public static function get_color() { return self::$color; } } class Dog extends Animal { public static $color = 'brown'; public static function get_color() { return self::$color; } }
Если вы можете создавать экземпляры – вы можете использовать get_class($this)
чтобы узнать вызывающий класс, например:
class Animal { public static $color = 'black'; public function getColor() // note, not static { $class = get_class($this); return $class::$color; } } class Dog extends Animal { public static $color = 'brown'; } $animal = new Animal(); echo $animal->getColor(); // prints 'black' $dog = new Dog(); echo $dog->getColor(); // prints 'brown'
Единственный другой вариант, о котором я думал, это использовать параметр функции для статической функции для определения класса, из которого он был вызван. Он может по умолчанию использовать __CLASS__
а затем вы можете return parent::get_class($class)
из подкласса. Подобный шаблон можно использовать для упрощения повторного использования статической функции (поскольку я сомневаюсь, что вы возвращаете публичное статическое свойство, это единственное, что вы пытаетесь использовать self::
in в этом статическом методе:
class Animal { public static $color = 'black'; public static function get_color($class = __CLASS__) { // Super Simple Example Case... I imagine this function to be more complicated return $class::$color; } } class Dog extends Animal { public static $color = 'brown'; public static function get_color($class = __CLASS__) { return parent::get_color($class); } }
В PHP 5.3+ было бы предпочтительным:
class Animal { public static $color = 'black'; public static function get_color() { return static::$color; // Here comes Late Static Bindings } } class Dog extends Animal { public static $color = 'brown'; } echo Animal::get_color(); // prints 'black' echo Dog::get_color(); // prints 'brown'
Поздние статические привязки (PHP.net)