АКЦИЯ: бесплатные месячные курсы по созданию сайтов
на выбор: верстка, JavaScript, PHP или фреймворки. Сегодня последний день для записи! Жми!
⊗ppOpBsGS 8 of 107 menu
Долгожданный Бесплатный курс по выкладке сайта на хостинг. МЫ УЖЕ НАЧАЛИ! Присоединяйтесь к нам!

Работа с геттерами и сеттерами в ООП на PHP

Давайте рассмотрим следующий класс:

<?php class User { public $name; public $age; // Метод для изменения возраста юзера: public function setAge($age) { // Проверим возраст на корректность: if ($this->isAgeCorrect($age)) { $this->age = $age; } } // Метод для проверки возраста: private function isAgeCorrect($age) { return $age >= 18 and $age <= 60; } } ?>

Как вы видите, у нас есть публичные свойства name и age, публичный метод setAge для изменения возраста и приватный метод проверки возраста isAgeCorrect.

Очевидно, что предполагается, что возраст всегда будет меняться через метод setAge, так как в нем выполняется проверка возраста на корректность.

Однако, ничего не мешает сделать так:

<?php $user = new User; // Вместо вызова setAge установим некорректный возраст напрямую: $user->age = 100500; // и у нас получится! ?>

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

Это ошибкоопасное место и с этим нужно что-то сделать.

Для решения проблемы можно объявить возраст приватным:

<?php class User { public $name; private $age; // объявим возраст приватным public function setAge($age) { // Проверим возраст на корректность: if ($this->isAgeCorrect($age)) { $this->age = $age; } } private function isAgeCorrect($age) { return $age >= 18 and $age <= 60; } } ?>

Теперь установить возраст напрямую (корректный или нет - не важно) не получится:

<?php $user = new User; // Теперь установить возраст напрямую не получится: $user->age = 100500; // увидим ошибку PHP! ?>

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

<?php $user = new User; // Правильным образом установим возраст: $user->setAge(50); // Попытка прочитать новый возраст приведет к ошибке PHP: echo $user->age; // а нам бы этого не хотелось... ?>

Для решения проблемы сделаем еще один метод getAge, с помощью которого мы будем прочитывать значения свойства age:

<?php class User { public $name; private $age; // объявим возраст приватным // Метод для чтения возраста юзера: public function getAge() { return $this->age; } public function setAge($age) { if ($this->isAgeCorrect($age)) { $this->age = $age; } } private function isAgeCorrect($age) { return $age >= 18 and $age <= 60; } } ?>

Теперь мы свободно можем и менять, и получать возраст:

<?php $user = new User; // Установим возраст: $user->setAge(50); // Прочитаем новый возраст: echo $user->getAge(); // выведет 50 ?>

Такой подход, который мы сейчас сделали, - стандартный. Его удобно использовать тогда, когда нам нужна какая-то проверка в сеттере. В терминах этого подхода метод getAge называется геттером (англ. getter), а метод setAge - сеттером (англ. setter).

Очень часто бывает так, что даже если нам не нужны никакие проверки - все равно свойство объявляется приватным, а для доступа к нему используются геттеры и сеттеры. Почему? Потому что, возможно, нам захочется добавить проверку в дальнейшем и, если все изменения свойства в коде делаются через сеттер, нам не придется вносить правки в код снаружи класса - мы просто внесем одну правку в сам сеттер.

Сделайте класс Employee, в котором будут следующие приватные свойства: name, age и salary.

Сделайте геттеры и сеттеры для всех свойств класса Employee.

Дополните класс Employee приватным методом isAgeCorrect, который будет проверять возраст на корректность (от 1 до 100 лет). Этот метод должен использоваться в сеттере setAge перед установкой нового возраста (если возраст не корректный - он не должен меняться).

Пусть зарплата наших работников хранится в долларах. Сделайте так, чтобы геттер getSalary добавлял в конец числа с зарплатой значок доллара. Говоря другими словами в свойстве salary зарплата будет хранится просто числом, но геттер будет возвращать ее с долларом на конце.