Reg.ru: домены и хостинг
Крупнейший регистратор и хостинг-провайдер в России.
Более 2 миллионов доменных имен на обслуживании.
Продвижение, почта для домена, решения для бизнеса.
Более 700 тыс. клиентов по всему миру уже сделали свой выбор.
Бесплатный Курс "Практика HTML5 и CSS3"
Освойте бесплатно пошаговый видеокурс
по основам адаптивной верстки
на HTML5 и CSS3 с полного нуля.
Фреймворк Bootstrap: быстрая адаптивная вёрстка
Пошаговый видеокурс по основам адаптивной верстки в фреймворке Bootstrap.
Научитесь верстать просто, быстро и качественно, используя мощный и практичный инструмент.
Верстайте на заказ и получайте деньги.
*Наведите курсор мыши для приостановки прокрутки.
Объектно-ориентированный подход в PHP для начинающих. Часть 2
Этот материал - продолжение статьи Объектно-ориентированный подход в PHP для начинающих. Часть 1.
В этой статье будут рассмотрены вопросы использования конструкторов, деструкторов и других магических методов в PHP. Кроме того, Вы узнаете о наследовании классов, а также перегрузке методов и свойств.
Магические методы в ООП
Чтобы упростить использование объектов, PHP также предоставляет некоторое количество магических методов (или специальных методов), которые вызываются, когда в пределах объекта происходят определенные действия. Это позволяет разработчикам выполнять некоторые полезные операции с большей легкостью.
Использование Конструкторов и Деструкторов
Когда мы создаем новый объект, часто бывает желательно сразу произвести определенные действия. Для того, чтобы осуществить это, PHP предлагает магический метод __construct(), который вызывается автоматически всякий раз, когда создается новый экземпляр класса.
Для иллюстрации работы конструктора добавьте в класс MyClass конструктор, который будет выводить на экран сообщение всякий раз при создании нового экземпляра класса:
<?php class MyClass { public $prop1 = "Я - свойство класса!"; public function __construct() { echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />'; } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } // Создаем новый объект $obj = new MyClass; // Получаем значение свойства $prop1 echo $obj->getProperty(); // Выводим сообщение в конце файла echo "Конец файла.<br />"; ?>
Замечание:
__CLASS__ - это константа, которая возвращает имя класса, в котором она была вызвана, одна из так называемых магических констант, подробнее о которых можно почитать в руководстве по PHP.
Перезагрузите страницу в браузере и Вы увидите такой результат:
Класс MyClass был инстанцирован! (Был создан экземпляр класса) Я - свойство класса! Конец файла.
Для того, чтобы выполнить определенные действия, когда объект уничтожается, нужно воспользоваться методом __destruct(). Это бывает полезно для очистки класса (например, для закрытия соединения с базой данных).
Давайте выведем соответствующее сообщение об уничтожении объекта с помощью данного метода:
<?php class MyClass { public $prop1 = "Я - свойство класса!"; public function __construct() { echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />'; } public function __destruct() { echo 'Объект уничтожен.<br />'; } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } // Создаем новый объект $obj = new MyClass; // Получаем значение свойства $prop1 echo $obj->getProperty(); // Выводим сообщение в конце файла echo "Конец файла.<br />"; ?>
При использовании деструктора после перезагрузки страницы мы получим следующий результат:
Класс MyClass был инстанцирован! (Был создан экземпляр класса) Я - свойство класса! Конец файла. Объект уничтожен.
"Когда достигнут конец файла, PHP автоматически освобождает все ресурсы"
Чтобы явно вызвать деструктор, Вы можете уничтожить объект с помощью функции unset():
<?php class MyClass { public $prop1 = "Я - свойство класса!"; public function __construct() { echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />'; } public function __destruct() { echo 'Объект уничтожен.<br />'; } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } // Создаем новый объект $obj = new MyClass; echo $obj->getProperty(); // Уничтожаем объект unset($obj); // Выводим сообщение в конце файла echo "Конец файла.<br />"; ?>
При обновлении страницы в браузере Вы увидите следующую картину:
Класс MyClass был инстанцирован! (Был создан экземпляр класса) Я - свойство класса! Объект уничтожен. Конец файла.
Обратите внимание, что вывод фразы "Объект уничтожен" теперь происходит раньше вывода фразы "Конец файла", т.к. в первом случае функция-деструктор срабатывала только после того, как в файле заканчивался весь код, а теперь мы явно уничтожаем объект раньше, что приводит к более раннему вызову деструктора.
Преобразование в Строку
Для того, чтобы избежать ошибки при попытке вывести объект как строку, следует использовать еще один магический метод - __toString().
Без его использования такая попытка приведет к фатальной ошибке:
<?php class MyClass { public $prop1 = "Я - свойство класса!"; public function __construct() { echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />'; } public function __destruct() { echo 'Объект уничтожен.<br />'; } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } // Создаем новый объект $obj = new MyClass; // Выводим объект как строку echo $obj; // Уничтожаем объект unset($obj); // Выводим сообщение в конце файла echo "Конец файла.<br />"; ?>
Выполнение этого кода приведет к следующему:
Класс MyClass был инстанцирован! (Был создан экземпляр класса) Catchable fatal error: Object of class MyClass could not be converted to string in... on line...
Для того, чтобы избежать этой ошибки воспользуемся методом __toString():
<?php class MyClass { public $prop1 = "Я - свойство класса!"; public function __construct() { echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />'; } public function __destruct() { echo 'Объект уничтожен.<br />'; } public function __toString() { echo "Используем метод __toString(): "; return $this->getProperty(); } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } // Создаем новый объект $obj = new MyClass; // Выводим объект как строку echo $obj; // Уничтожаем объект unset($obj); // Выводим сообщение в конце файла echo "Конец файла.<br />"; ?>
В этом случае, попытка вывести объект как строку ведет к обращению к методу getProperty().
Следует помнить о том, что метод __toString() вызывается только, если объект встречается напрямую в echo() или print().
Обновив страницу, Вы увидите:
Класс MyClass был инстанцирован! (Был создан экземпляр класса) Используем метод __toString(): Я - свойство класса! Объект уничтожен. Конец файла.
Примечание:
Помимо тех магических методов, которые мы рассмотрели, существуют и другие. Для того, чтобы увидеть весь список этих методов, обратитесь к руководству по PHP
Наследование Классов
Классы могут наследовать методы и свойства других классов благодаря использованию ключевого слова extends. Например, для того, чтобы создать второй класс, который наследует класс MyClass и который имеет внутри себя метод, нужно поступить следующим образом:
<?php class MyClass { public $prop1 = "Я - свойство класса!"; public function __construct() { echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />'; } public function __destruct() { echo 'Объект уничтожен.<br />'; } public function __toString() { echo "Используем метод __toString(): "; return $this->getProperty(); } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } class MyOtherClass extends MyClass { public function newMethod() { echo "Из нового метода в классе " . __CLASS__ . ".<br />"; } } // Создаем новый объект $newobj = new MyOtherClass; // Выводим объект как строку echo $newobj->newMethod(); // Используем метод из родительского класса MyClass echo $newobj->getProperty(); ?>
Перезагрузите страницу и Вы увидите следующее:
Класс MyClass был инстанцирован! (Был создан экземпляр класса) Из нового метода в классе MyOtherClass. Я - свойство класса! Объект уничтожен.
Именно наследование приводит к тому, что при создании экземпляра класса MyOtherClass мы можем обращаться как к методам родительского класса MyClass, так и к методам самого класса MyOtherClass (который является дочерним по отношению к MyClass).
Перезапись (перегрузка) унаследованных Свойств и Методов
Для того, чтобы изменить значение или поведение существующего свойства или метода в новом классе, Вы можете просто перезаписать (перегрузить) его, объявив его в новом классе:
<?php class MyClass { public $prop1 = "Я - свойство класса!"; public function __construct() { echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />'; } public function __destruct() { echo 'Объект уничтожен.<br />'; } public function __toString() { echo "Используем метод __toString(): "; return $this->getProperty(); } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } class MyOtherClass extends MyClass { public function __construct() { echo "Новый конструктор из класса " . __CLASS__ . ".<br />"; } public function newMethod() { echo "Из нового метода в классе " . __CLASS__ . ".<br />"; } } // Создаем новый объект $newobj = new MyOtherClass; // Выводим объект как строку echo $newobj->newMethod(); // Используем метод из родительского класса MyClass echo $newobj->getProperty(); ?>
Это приведет к следующим изменениям на странице:
Новый конструктор из класса MyOtherClass. Из нового метода в классе MyOtherClass. Я - свойство класса! Объект уничтожен.
Здесь, как Вы можете видеть, в классе MyOtherClass мы перегрузили метод __construct(), что привело к выводу нового сообщения.
Сохранение исходной функциональности Метода при его перегрузке
Чтобы добавить новые функциональные возможности к унаследованному методу, сохраняя при этом оригинальный метод нетронутым, используйте ключевое слово parent с оператором (::). Рассмотрим это на примере функции-конструктора в классе MyOtherClass:
<?php class MyClass { public $prop1 = "Я - свойство класса!"; public function __construct() { echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />'; } public function __destruct() { echo 'Объект уничтожен.<br />'; } public function __toString() { echo "Используем метод __toString(): "; return $this->getProperty(); } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } class MyOtherClass extends MyClass { public function __construct() { parent::__construct(); // Вызываем конструктор родительского класса (MyClass) echo "Новый конструктор из класса " . __CLASS__ . ".<br />"; } public function newMethod() { echo "Из нового метода в классе " . __CLASS__ . ".<br />"; } } // Создаем новый объект $newobj = new MyOtherClass; // Выводим объект как строку echo $newobj->newMethod(); // Используем метод из родительского класса MyClass echo $newobj->getProperty(); ?>
Такой подход приведет к тому, что на экран будут выведены результаты выполнения как конструктра родительского класса MyClass, так и дочернего класса MyOtherClass:
Класс MyClass был инстанцирован! (Был создан экземпляр класса) Новый конструктор из класса MyOtherClass. Из нового метода в классе MyOtherClass. Я - свойство класса! Объект уничтожен.
По материалам net.tutsplus.com
Перевод - Дмитрий Науменко.
P.S. Хотите двигаться дальше в освоении PHP и ООП? Обратите внимание на премиум-уроки по различным аспектам сайтостроения, включая программирование на PHP, а также на бесплатный курс по созданию своей CMS-системы на PHP с нуля с использованием ООП:
Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!
Смотрите также: