Генератор календаря на PHP с подсветкой событий

Статья рассчитана на пользователей, хорошо знакомых с объектно-ориентированным программированием.

Сейчас я расскажу о новой полезной возможности, которая была введена с ветки 5 в качестве развития ООП в PHP (по сравнению с веткой 4). Она называется «цепочки вызовов» (Method Chaining) и выглядит следующим образом:

  1. $object>method_a()>method_b()>method_c();

Что же здесь на самом деле происходит? Начнем с того, что одно из (многих) изменений между PHP4 и PHP5 заключается в том, что теперь методы могут возвращать объекты. Это небольшое изменение позволяет по-новому использовать ООП. Итак, для того, чтобы пользоваться цепочками вызовами у вас должна быть возможность возвращать из метода объекты. Причем не существенно что это будет за объект — текущего класса, или совершенно другого.

Обычное использование класса
Начнем с самого обыкновенного класса и его использования.

  1. class Person
  2. {
  3. private $m_szName;
  4. private $m_iAge;
  5. public function setName($szName)
  6. {
  7. $this>m_szName = $szName;
  8. }
  9. public function setAge($iAge)
  10. {
  11. $this>m_iAge = $iAge;
  12. }
  13. public function introduce()
  14. {
  15. printf(
  16. ‘Hello my name is %s and I am %d years old.’,
  17. $this>m_szName,
  18. $this>m_iAge);
  19. }
  20. }

Теперь мы можем создать экземпляр класса Person и передать в объект имя и возраст. После чего, воспользовавшись методом introduce вывести на экран информацию о человеке:

  1. $peter = new Person();
  2. $peter>setName(‘Peter’);
  3. $peter>setAge(23);
  4. $peter>introduce();

В результате выполнения данного примера, на экран будет выведена строка:

  1. Hello my name is Peter and I am 23 years old.

Использование цепочных вызовов
На самом деле, отличий в коде будет совсем немного. Мы добавим всего 2 строки. Как же это будет работать? Очень просто! Нам нужно возвращать объект класса Person из каждого метода. Наш исходный класс будет выглядеть так:

  1. class Person
  2. {
  3. private $m_szName;
  4. private $m_iAge;
  5. public function setName($szName)
  6. {
  7. $this>m_szName = $szName;
  8. return $this; //Возвращаем объект текущего класса
  9. }
  10. public function setAge($iAge)
  11. {
  12. $this>m_iAge = $iAge;
  13. return $this; //Возвращаем объект текущего класса
  14. }
  15. public function introduce()
  16. {
  17. printf(
  18. ‘Hello my name is %s and I am %d years old.’,
  19. $this>m_szName,
  20. $this>m_iAge);
  21. }
  22. }

Пример использования модифицированного класса:

  1. $peter = new Person();
  2. $peter>setName(‘Peter’)>setAge(23)>introduce();

На экран будет выведено абсолютно тоже самое, что и в изначальном примере.

Как это работет
Сначала мы выполняем $peter->setName(‘Peter’). Этот метод заполнит имя и вернет $this — текущий объект. Теперь нам нужно заполнить возраст. Следующее действие ->setAger(23). Поскольку мы записали вызов в цепочку, PHP интерпретирует это как «запустить метод setAge, принадлежащий тому, что вернул предыдущий метод». В данном случае Person ($peter).

Абсолютно тоже самое происходит при вызове introduce. PHP запустит метод, обратившись к объекту возвращенному из предыдущей операции.

Записывать методы в цепочку можно в любой последовательности и с любыми повторениями:

  1. $peter>setAge(23)
  2. >setName(‘Peter’)
  3. >setName(‘Winifred’)
  4. >setAge(72)
  5. >introduce();

В данном случае на экран будет выведена строка

  1. Hello my name is Winifred and I am 72 years old.