Позднее статическое связывание в PHP 5.3 – рассмотрим примеры
С выходом PHP 5.3 появилась функциональность “позднего статического связывания”. Многие разработчики были озадачены данной особенностью в более ранних версиях PHP, но, вероятно, не знали, что она имеет название. В данной статье рассматривается проблема, возникающая при статическом связывании и как её избежать в PHP 5.3.

Позднее статическое связывание в PHP 5.3
Конечно, лучше показать проблему на примере. Здесь мы имеем класс Record, от которого будут происходить остальные классы (это сильно упрощенный пример и от него мало пользы, но, во всяком случае, он показывает проблему):
class Record {
protected static $tableName = 'base';
public static function getTableName() {
return self::$tableName;
}
}
Теперь можно определить пользовательский класс, он будет включать собственную переменную, но функция getTableName будет унаследована, поскольку она идентична той, которая объявлена в родительском классе.
class User extends Record {
protected static $tableName = 'users';
}
Теперь, если вызвать метод getTableName в классе User, какой бы вы ожидали результат:
User::getTableName(); // возвращает "base"
Не совсем то, что ожидалось. Это вполне обычная вещь, которую требуется сделать. Я часто видел, что люди сталкиваются с этой проблемой при реализации шаблона активной записи (Active Record), когда создают многоразовые виджеты форм в своих собственных шаблонах и приложениях. В PHP 5.3 ключевое слово static реализовано, чтобы позволить получить значение класса, код которого выполняется в данный момент, а не родительского класса. Для этого в классе Record необходимо только заменить ключевое слово “self” на “static”:
class Record {
protected static $tableName = 'base';
public static function getTableName() {
return static::$tableName;
}
}
Данное ключевое слово по-другому получает значение, учитывая контекст, из которого происходит вызов. Теперь, если повторить вызов метода getTableName в классе User.
User::getTableName(); // возвращает "users"
Так намного лучше!
Данная функция не решает проблему полностью, ключевое слово self по-прежнему указывает на родительский класс, поэтому разработчики будут сталкиваться с неожиданным поведением и получать соответствующие значения родительского класса. Однако теперь существует решение в виде нового ключевого слова static. Я уверен, что данная особенность будет полезна в широком диапазоне приложений.


0 Comments
You can be the first one to leave a comment.