ООП в php магічні методи

Не менш значущі, на мій погляд, магічні методи це методи-перехоплювачі __get. __set. __isset. __unset. __call. Назвали їх так за те, що вони немов перехоплюють звернення до недоступним або неіснуючим членам класу.
Методи __get і __set
Ці методи спрацьовують при зверненні до неіснуючих або недоступним полів класу або його предка. Вони повинні бути оголошені з специфікатором доступу public. При цьому метод __get викликається при спробі вважати значення прихованого або неіснуючого властивості. Як параметр він приймає рядок, що містить ім'я властивості до якого сталася спроба звернутися. Що повертається цим методом значення буде сприйнято як значення властивості, до якого відбулося звертання, при цьому неважливо приховано це властивість, або воно зовсім не існує.
Результат роботи цього скрипта:
Сталося звернення до властивості x
x: 8
Сталося звернення до властивості y
y: 16
Сталося звернення до властивості nonexistentProperty
Неіснуючі поле:
Як бачите, метод __get при такій реалізації при зверненні до неіснуючого властивості повертає значення null. яке в нашому прикладі перетворилося до порожньому рядку.
Метод __set викликається при спробі змінити значення неіснуючого або прихованого властивості. Як параметри він приймає ім'я властивості і значення, яке йому намагаються привласнити. Додамо цей метод в наш клас Point.
Тепер при кожній спробі змінити значення прихованого або неіснуючого властивості буде виводитися відповідне повідомлення.
$ P = new Point (8, 16); $ P-> x = 10; $ P-> y = 20; $ P-> z = 30;
Результат роботи цього скрипта:
Властивості x присвоєно значення 10
Властивості y присвоєно значення 20
Властивості z присвоєно значення 30
Методи __get і __set корисні тим, що з їх допомогою можна емулювати наявність властивості, якого немає. При цьому можна зробити так, що не заглядаючи всередину класу, про це не можна буде ніяк здогадатися. Наприклад, у нас є клас, що описує квадрат з одним прихованим полем, яке містить довжину сторони квадрата (side).
Емулюючи наявність у цього класу властивості «площа» (area). При цьому врахуємо, що площа квадрата і довжина його боку залежать один від одного.
Тепер екземпляри цього класу будуть вести себе так, немов властивість area присутній в класі, а властивість side є ззовні.
$ Squere = new Squere (25); echo $ squere-> area; // 25 * 25 = 625
При цьому нам не потрібно буде піклуватися про те, що площа квадрата залежить від довжини його сторони.
$ Squere = new Squere (10); echo $ squere-> side; // 10 $ squere-> area = 25; echo "Після зміни площі змінилася і сторона:
"." $ Squere-> side "; // 5 = sqrt (25)
Абсолютно того ж можна було домогтися і при використанні методів, але в такому випадку для отримання або зміни значення кожного поля довелося б писати свій власний метод, що досить складно, особливо якщо полів у класу багато. У деяких середовищах розробки, наприклад, в NetBeans навіть передбачена автоматична генерація таких методів.
Методи, які організовують доступ до полів класу, називають Геттера (служать для отримання значень) і сетерами (служать для зміни значень). Як правило, код в цих методах шаблонний і очевидний. Пишуться вони для запобігання присвоєння некоректних значень властивостей класу. Наприклад, у нас є клас, що описує людину. Примірник цього класу зберігає інформацію про його ім'я та вік. За допомогою геттеров і сеттерів забезпечується коректність цих даних.
$ Man = new Man ( 'Jhon Doe', 21); $ Man-> setAge (-2); // Некоректне вік. Відбудеться завершення роботи скрипта
Бути може в цьому випадку код став трохи заплутаніше, але іноді, коли перевірка привласнюються властивостям значень однакова або чимось схожа такий прийом може трохи скоротити і поліпшити ваш код. Крім того в цьому прикладі ми заборонили звертатися до неіснуючих властивостей класу. Така заборона можливо врятує вас в майбутньому від деяких помилок.
Емулювання властивостей іноді називають перевантаженням, але в багатьох інших мовах під навантаженням розуміють трохи інше явище тому, щоб не вас не запитати, я вважав за краще не використовувати це неоднозначне поняття.
метод __isset
При імітації властивостей за допомогою методів __get і __set завжди потрібно пам'ятати, що реально таких властивостей не існує. Але використовувати ваш клас може і інший програміст, і імітовані властивості можуть бути прийняті їм за реально існуючі. Здавалося б, в цьому немає нічого поганого, але при спробі перевірити наявність імітованого властивості за допомогою функції isset можна отримати несподіваний результат:
$ P = new Squere (10); // наявність властивості area в класі Squere імітовано var_dump (isset ($ p-> area)); // bool (false)
Щоб уникнути подібних непорозумінь існує магічний метод __isset. який викликається при спробі перевірити наявність недоступного або неіснуючого властивості за допомогою функції isset. Що повертається методом __isset логічне значення і говорить, чи слід вважати властивість існуючим.
Додамо реалізацію методу __isset в клас Squere:
Антон, хотілося б подякувати Вам за уроки, продовжуйте в тому ж дусі, для себе нарешті то розумію деякі речі, які важко було засвоїти з інших джерел, спасибі! Ну і питання: в коді, де описуються методи __get і __set, де обчислюється площа квадрата, 18-а строчка return $ this-> getArea ($ value); вірна вона? Ми передаємо в функцію getArea параметр, але при описі функції, вхідних параметрів немає, і взагалі змінна $ value до цього моменту не инициализирована?
Там помилка. Виправив. Дякую за зауваження.