Getter’и та Setter’и
PHP. Особливості та фічі
Прямий ефір
hui_nana 28 травня 2014, 13:33
Grover 26 травня 2014, 11:42
Grover 26 травня 2014, 11:41
hui_nana 23 травня 2014, 10:26
- Frontend7.96
- Yii framework7.92
- Q&A6.03
- OS Linux5.66
- CMS 1C-Bitrix5.65
- PHP. Продукти4.63
- PHP. Продуктивність4.53
- PHP. Особливості та фічі4.53
- Безпека4.52
- HTML51.25
Джозеф Кроуфорд, один із моїх читачів, прочитав статтю про те, як я не люблю писати getter'и та setter'и і припустив, що я можу використовувати чарівні методи __get та __set. Я скажу вам, чому це не дуже хороша ідея використовувати їх звичайним способом. Крім того, я збираюся розповісти вам історію, де вони справді виявилися корисними, — йтиметься про створення статичних типів у PHP (динамічна мова). Для тих, хто не знайомий з методами __get і __set — це два «магічні» методи, які працюють таким чином:
Як правило, перераховані вище методи використовуються для створення динамічних властивостей. Який висновок можна із цього зробити? Якщо ви хочете створювати будь-які випадкові властивості, просто використовуйте хеш (він же масив із ключами). Що ж хорошого в getter'ах та setter'ах? Давайте подивимося:
Що? Вага із негативним значенням? Це з більшості поглядів неправильно. Корова не повинна важити менше 100 кг (я так думаю:). У межах 1000 – допустимо. Як нам забезпечити таке обмеження. Використовувати __get та __set — досить швидкий спосіб.
А що якщо у вас є клас із 10—20 властивостями та перевірками для них? Уцьому разі неприємності неминучі.
І навпаки, getter'и та setter'и виявляють себе з кращого боку, коли справа доходить до перевірки даних.
Ніщо не порівнюється з короткими функціями з C#. Можливо, така підтримка скоро з'явиться в PHP, ну а поки не розслабляємося ... Кожен спосіб несе відповідальність тільки за свою область, завдяки цьому в коді легше орієнтуватися. Все одно виходить занадто багато коду, але він чистіший, ніж __set-версія. Існує хороший евристичний підхід, який полягає в наступному: якщо ваш метод (функція) займає більше ніж 1 екран – потрібно скорочувати. Це покращить сприйняття коду. Ми також зберігаємо деяку бізнес-логіку. Копит завжди буде рівно стільки, скільки і ніг, а якщо ми помітимо зміну ваги худоби, ми відразу повідомимо пастуха. Оскільки ми не дбаємо про прізвиська корів і не перевіряємо їх, нехай дані будуть загальнодоступними без getter'ів і setter'ів. Знову ж таки, я дійсно не писав всіх цих getter'ів і setter'ів — PHP Storm зробив це за мене. Я просто написав таке:
і натиснув Alt+Insert -> Getters та setters. PHPStorm згенерував все автоматично. Тепер у вигляді додаткової переваги PHP Storm при роботі з getter'ами та setter'ами маю можливість використовувати функцію автозаповнення:
У випадку __get я не маю такої можливості, я можу лише написати це:
Тепер корова "важить" (wIEghts) мінус 100 кг. Я можу забути, що це вага в кг, досить просто написати weight - все працюватиме. Отже, getter'и and setter'и бувають дуже навіть корисні (але все ж таки не поклоняйтеся їм, ви ж не програміст Java). Якщо вам просто потрібні вільні властивості, використовуйте масив:
Цей трюк набагато легшепровернути, ніж __get та __set. Але, якщо ви хочете бути впевненим, що ваші дані завжди мають лише допустимі значення, використовуйте setter'и з перевіркою. За наявності інтегрованого середовища розробки (IDE), типу PHP Storm, ви любитимете setter'и, тому що вони дуже прості у використанні. Замість $cow->setLegs() для PHP Storm достатньо буде набрати co[TAB]sl[TAB]. Та легко! Немає більше друкарських помилок, і ви можете бачити, які параметри приймає метод. Метод __set має ще один недолік. Він приймає лише один параметр. Що робити, якщо вам потрібно 2? Наприклад, як тут: $store1->setPrice('item-1', 100). Вам необхідно встановити ціну товару у магазині. Метод __set не дозволить вам цього зробити, а setter дозволить.