Наследование класса в PHP 5.2: переопределение статической переменной в классе расширения?

Мне нужно иметь возможность использовать статическую переменную, установленную в классе, которая расширяет базовый класс... из базового класса.

Рассмотрим это:

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, поэтому мне нужно адаптировать мой script.

Есть ли какое-то довольно обходное решение для решения этой проблемы?

Ура!
Кристоффер

РЕДАКТИРОВАТЬ: Цель

Как отмечено ниже, это очень упрощенный пример того, что я пытаюсь выполнить. Если я предоставил вам два варианта, которые я использовал для решения моей проблемы (и сама проблема), у кого-то может быть другое решение, чем у меня...

Я создал базовую модель базы данных, которая содержит такие функции, как "find", "find_by" и "find_all" (все статические).

В PHP 5.3 существует функция под названием get_called_class(), которую я использую в настоящее время для определения имени вызываемого класса, а затем используйте ее для сопоставления с соответствующей таблицей базы данных. Класс Ex User указывает на users.

get_called_class() не существует в PHP 5.2.x, и реализованные вами реализации hack очень ненадежны. Затем я обратился к этому варианту использования статической переменной во всех классах моделей, которые содержат имя класса.

Ответ 1

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

Ответ 2

Я столкнулся с этой проблемой при подклассификации чего-то в 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:: для этого статического метода:

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);
    }
}

Ответ 3

В 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)