Вісім причин використовувати phpdoc
Ні, це не зовсім синтаксис PHP. А точніше, до самого PHP він ніякого відношення не має і сам PHP інтерпретатор його ніколи не парсит. Це PHPDoc-блок, що зародився ще як JavaDoc і перейшов в PHPDocumentor
Поки ми не Кодима так, як запалюють ці чуваки:
але спробуємо розібратися.
Всі ці речі, судячи з назви, як-то пов'язані з документацією. З неї і почнемо.
документація коду
Якщо подивитися в API Reference і в код класу то побачимо одне і те ж:

Тепер зрозуміло, як цей сайт так швидко змінюється при кожному оновленні початкових кодів. Виявляється, що він складений не вручну, а автоматично згенерований за кодом фреймворка.
Так що можемо вже сформулювати перший бонус, який нам дають PHPDoc-блоки:
Застосування перша: Можливість однією командою в консолі згенерувати документацію з описом всіх класів, полів і методів свого проекту.
Але крім цього ніж він корисний в реальному житті? Розглянемо ще кілька застосувань.
Віртуальні поля
У моделі він стане в нагоді для тієї ж автогенерации по класу цієї моделі, але для чого його використовують в предстваленіях, які в документації не виводяться?
Наприклад, був клас без полів:
і незрозуміло що там, так як Yii2 бере атрибути з таблиці в базі даних. Автопідстановка бачить тільки поля і методи з базового класу ActiveRecord:

А наші поля підкреслює, при цьому лаючись, що їх в об'єкті немає:
Можна задурити і написати плагін, який би Парс поля з бази для кожної моделі. Але це явно не легкий шлях.

Тепер він в курсі наших справ і більше не лається.
Або якщо в моделі є зв'язки:
У коді ми можемо використовувати їх просто як поля category. user і tags:
Але цих полів в класі немає. Все працює через віртуальні методи і геттери. Тому нам нічого не залишається, як вказати ці псевдополя і їх типи явно:
Так що PHPDoc-блок перед класом може містити повне перерахування того, чого в класі немає.
Застосування друге: Вказівка псевдополей класу.
У прикладах ми розглянули поки тільки поля. До псевдометодам підійдемо пізніше.
Типи існуючих полів
Крім блоку перед класом можна використовувати і інші місця.
Припустимо, що у нас є приватне поле _user у класу PasswordChangeForm:

А якщо ми підкажемо, що там у нас знаходиться модель класу User:
то все запрацює як нам цього і хотілося.
Тут ми анотації @var передаємо тільки тип. Але взагалі їй можна передавати ім'я змінної, її тип або обидва аргументи відразу.
Застосування третя: Підказка типів для наявних полів в класі.
Тип повертається результату
Аналогічно, якщо ми анотацією @return вкажемо тип повертається методом об'єкта:
то при використанні цього методу наша система розробки зрозуміє, що всередині змінної $ user після виклику даного методу виявиться модель класу User:
і більше не буде лаятися на раніше невідомі їй методи load і save.
А що якщо який-небудь метод повертає нам або User. або null. Тоді можна перерахувати варіанти через вертикальну риску:
І IDE буде враховувати обидва випадки.
Застосування четверта: Підказка типів аргументів і типу що повертається результату (при наявності) у процедур, функцій, методів.
Змінні з нізвідки
Або ще варіант. Є певне уявлення, в яке з контролера передається змінна $ model. До того ж, це уявлення рендерится в об'єкті класу \ yii \ web \ View. який і буде доступний через $ this:
Але IDE не в курсі наших планів, тому відразу підсвічує змінні $ this і $ model що не визначені в цьому файлі. Для виправлення ситуації ми можемо додати скільки завгодно Doc-блоків з анотацією @var прямо всередину коду уявлення:
При цьому для @var можна вказати спочатку тип, потім ім'я змінної:
В результаті автопідстановка, пошук і автозамена полів і методів об'єктів запрацюють для цих змінних автоматично.
Застосування п'ята: Позначення змінних, яким-небудь чином переданих ззовні.
підміна типу
Не завжди ми в контролерах та інших компонентах використовуємо метод findModel. Часто можна безпосередньо в коді виконати який-небудь запит:
В результаті IDE по ланцюжку спадкування підгляне анотації методу ActiveRecord :: find:
і, так як вказана анотація @inheritdoc. піде ще вище в анотації цього ж методу в інтерфейсі:
і склеїть все воєдино.
В результаті IDE по рядку:
зрозуміє, що з методу find повинен повернутися екземпляр класу \ yii \ db \ ActiveQuery і методи where і one будуть викликатися вже у нього:
Для правильної роботи нам потрібно явно вказати тип змінної за допомогою Doc-блоку перед привласненням:
або безпосередньо перед використанням об'єкта:
Це зручно робити в циклах з різних вибірках:
Застосування шоста: Підміна типу вже існуючих змінних.
І повернемося до методів.
підключення домішок
Спочатку ми розглянули віртуальні змінні. Тепер припустимо, що до своєї моделі ми підключаємо будь-яка поведінка на кшталт:
Його досить додати в метод behaviors моделі:
і в уявленнях виводити оригінал або превью:
А ми пам'ятаємо, що IDE лається на все, чого немає в класі. Але за допомогою анотації @mixin. яку підтримує IDE PhpStorm і, можливо, деякі інші, можна «підмішати» клас поведінки:
і все методи getImageFileUrl і інші будуть доступні в автопідстановки вже нашої моделі.
Але є один нюанс. Крім потрібних методів в класі поведінки є і багато непотрібних. Наприклад, допоміжні resolveProfilePath або createThumbs. які ми використовувати не будемо.
У такому випадку замість прімешаванія всього класу поведінки за допомогою @mixin ми можемо просто додати визначення тільки пари потрібних нам віртуальних методів:
Аналогічно можна додавати сигнатури будь-яких своїх методів, які працюють через свій магічний метод __call.
Застосування сьома: Визначення псевдометодов класу.
Програмування з анотаціями
Крім простої роботи з PHPDocumentor деякі системи пішли далі і придумали для своїх цілей власні види анотацій. І якийсь програмний код через рефлексію парсит ці дані. Взяти хоч перший-ліпший приклад з сайту StackOverflow:
Аналогічно можна отримати $ r-> getMethods () і парсити вже їх.
У підсумку цей підхід знайшов нове застосування. Наприклад, в Symfony Framework за допомогою власних анотацій (крім конфігурації в YAML або XML-файлах) можна конфігурувати ті ж сутності прямо в коді:
або ту ж маршрутизацію контролерів:
І фреймворк легко парсит ці дані і кешує в прості PHP-масиви, щоб не парсити їх кожен раз знову і знову.
Також в уроці з тестування ми розглядали анотації на кшталт @group і @dataProvider для тестів в пакеті PHPUnit.
Цей підхід вже мало пов'язаний з оригінальним PHPDoc, так як просто використовує його ідею. Але при цьому один одному ніхто не заважає і можна спокійно використовувати різні ключі разом:
Багатьом такий підхід з конфігурацією анотаціями в Symfony не подобається, так як він порушує принцип єдиної відповідальності, змішуючи програмний код і конфігурацію в одному файлі. Так що використовуйте на свій розсуд.
Восьма причина: Поява програмних систем з підтримкою специфічних анотацій.
Після цього не буде проблем з автопідстановки, помилками, розбіжностями типу, невизначеними змінними, з автоматичним перейменуванням полів або методів будь-якого класу і іншим автоматичним рефакторингом.
Дружите зі своєю IDE і вона полегшить ваше життя.
Ну і, начебто, свято скоро, так що не спалите ялинку: