Denis.in.ua

Блог имени Меня

Позднее статическое связывание в PHP (Часть I)

2 comments

phpПозднее Статическое Связывание (Late Static Binding, LSB) является бурно темой обсуждений последние три года в кругах разработчиков PHP (и наконец мы его получили в PHP 5.3). Но зачем оно нужно? В данной статье, как раз и будет рассматриваться, как позднее статическое связывание может значительно упростить ваш код.

На встрече разработчиков PHP, которая проходила в Париже в ноябре 2005 года, тема позднего статического связывания официально обсуждалась основной командой разработчиков. Они согласились реализовать его, наряду со многими другими темами, которые стояли на повестке дня. Детали должны были быть согласованы в ходе открытых дискуссий.

С тех пор как позднее статическое связывание было объявлено как грядущая фишка, прошло два года. И вот наконец LSB стало доступно для использования в PHP 5.3. Но это событие прошло незаметно для разработчиков использующих PHP, из заметок только страничка в мануале.

Если кратко, новая функциональность позднего статического связывания, позволяет объектам все также наследовать методы у родительских классов, но помимо этого дает возможность унаследованным методам иметь доступ к статическим константам, методам и свойствам класса потомка, а не только родительского класса. Давайте рассмотрим пример:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Beer {
    const NAME = 'Beer!';
      public function getName() {
          return self::NAME;
    }
}
class Ale extends Beer {
    const NAME = 'Ale!';
}

$beerDrink = new Beer;
$aleDrink = new Ale;

echo "Beer is: " . $beerDrink->getName() ."\n";
echo "Ale is:  " . $aleDrink->getName()  ."\n";

Этот код выдаст такой результат:

1
2
Beer is: Beer!<br />
Ale is:  Beer!

Класс Ale унаследовал метод getName(), но при этом self все еще указывает на класс в котором оно используется (в данном случае это класс Beer). Это осталось и в PHP 5.3, но добавилось слово static. И снова рассмотрим пример:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Beer {
  const NAME = 'Beer!';
  public function getName() {
      return self::NAME;
  }
  public function getStaticName() {
      return static::NAME;
  }
}

class Ale extends Beer {
  const NAME = 'Ale!';
}

$beerDrink = new Beer;

$aleDrink = new Ale;

echo "Beer is: " . $beerDrink->getName() ."\n";
echo "Ale is:  " . $aleDrink->getName()  ."\n";

echo "Beer is actually: " . $beerDrink->getStaticName() ."\n";
echo "Ale is actually:  " . $aleDrink->getStaticName()  ."\n";

Новое ключевое слово static указывает, что необходимо использовать константу унаследованного класса, вместо константы которая была определена в классе где объявлен метод getStaticName(). Слово static было добавлено, чтобы реализовать новый функционал, а для обратной совместимости self работает также как и в предыдущих версиях PHP.

Внутренне, основное отличие (и, собственно, причина почему связывание назвали поздним) между этими двумя способами доступа, в том, что PHP определят значение для self::NAME во время «компиляции» (когда симовлы PHP преобразуются в машинный код, который будет обрабатываться движком Zend), а для static::NAME значение будет определено в момент запуска (в тот момент, когда машинный код будет выполнятся в движке Zend).

Это еще один инструмент для PHP-разработчиков. Во второй части рассмотрим как его можно использовать во благо.

Перевод вот этого: Late Static Binding: a practical example

Written by Денис Солошенко

Апрель 7th, 2008 at 12:20 пп

Posted in PHP