inheritdoc php что это
Создание документации на основе PhpDocumentor или немного про комментирование кода
PhpDocumentor автоматически генерирует из исходного кода документацию. Поэтому скрипт покажет лучший вариант только при правильном построении комментариев, именно это мы и разберем в первую очередь.
Описание функций, методов, файлов и переменных
Описание идёт таким образом:
/**
* Краткое описание
*
* Подробное описание
* которое возможно в несколько строк
*
* @тег значение
*/
Сразу пример, который далее мы немного разберём.
file1.php
* @version 1.0
* @package files
*/
/**
* Подключаем файл
*/
include_once ‘file2.php’;
/**
* Просто класс
* @package files
* @subpackage classes
*/
class Test2 extends Test <
file2.php
* @version 1.0
* @package files
*/
Описание примера
Разбирать местоположение комментариев мы не будем, рассмотрим саму структуру.
@package Название
Логически объединяет файлы, классы, методы и тд. Долно быть сделано с умом или вообще не сделано. В PhpDocumentor возможно потом просматривать подобно категориям на сайте
@subpackage Название
Аналогично>return, но действует как подгруппа.
global [private | protected | public]
Доступ к элементу
copyright Текст
Копирайты. Думаю всё ясно.
@category Название
Используется для организации групп. Полезно если портируете в XML формат, иначе смысла нет.
example Сылка|Путь
Ссылка или путь на пример работы
global
Игнорирование элемента. Иногда удобно.
@license Url
Ссылка на лицензию
link URL Описание ссылка
Формирование ссылки
see Тип Описание
Используется только для переменных класса
@Echo Off
for /f «tokens=1,2» %%a in (‘dir /s /b *.cs’) do ren %%a %%
nxas
for /f «tokens=1,2» %%a in (‘dir /s /b *.pn’) do ren %%a %%
nxag
for /f «tokens=1,2» %%a in (‘dir /s /b *.tp’) do ren %%a %%
Inheritance
phpDocumentor is capable of inheriting a large amount of information from elements in superclasses and super-interfaces that have been overridden and in the case of classes and interfaces even from a superclass itself.
For ease of reading this document has been separated into three parts:
In each of these chapters we will describe how information is inherited for that specific element. If you read carefully then you will notice that they differ little, mostly varying in which tags are inherited and how each tag is influenced by a super-element.
Interfaces and classes are treated equally with regards to inheritance, as such whenever we refer to a class we also mean an interface to make the text easier on the eyes.
The inheritDoc tag
Before we discuss how the documentation for each element is inherited it is interesting to point out the inheritDoc tag. The inline tag <@inheritDoc>is used in a description to import the description of a parent element, even if the child element already has a description.
So let us look at an example. In the following code block we re-define (override) a method of an imaginary superclass:
Now suppose that the overridden method has the description This is the description specific to the overridden method. ; the description of the re-defined method will be:
As you can see, the two descriptions have been combined into one, where the overridden element’s description has been inserted in the location of the <@inheritDoc>inline tag.
Currently some applications have DocBlocks containing just the <@inheritDoc>inline tag to indicate that their complete contents should be inherited. This usage breaks with the PHPDoc Standard as summaries cannot contain inline tags and inheritance is automatic; you do not need to define a special tag for it.
However, it does make clear that an element has been explicitly documented (and thus not forgotten). As such we are working to include a new (normal) tag in the PHPDoc Standard @inheritDoc that will serve that purpose.
Classes and interfaces
Perhaps the simplest of all elements, because a DocBlock for a class makes full use of the object-oriented principles that PHP offers and inherits the following information from the superclass (unless overridden):
As hinted at in the opening text of this chapter each of the above will only be inherited if the child’s DocBlock does not have the inherited element. So, for example, if the DocBlock of a subclass has a summary then it will not receive the superclass’ summary.
The @subpackage tag will only be inherited if the parent’s @package matches the @package tag of the subclass; otherwise subpackages would ‘bleed’ through into other packages where they are not desired.
Properties
Inheritance for properties functions similar to classes and interfaces. When a superclass of the current class contains a property with the same name (hence, this property is re-defined) then the following information is inherited from that overridden property:
As with classes, each of the above will only be inherited if the redefined property’s DocBlock does not have the element that is to be inherited. So, for example, if the DocBlock of the redefined property has a summary then it will not receive the overridden property’s summary.
Methods
Inheritance for methods functions similar to classes and interfaces. When a superclass of the current class contains a method with the same name (hence, this method is re-defined) then the following information is inherited from that overridden method:
As with classes, each of the above will only be inherited if the redefined method’s DocBlock does not have the element that is to be inherited. So, for example, if the DocBlock of the redefined method has a summary then it will not receive the overridden method’s summary.
Рекомендуемые XML-теги для комментариев к документации по C#
В комментариях к документации по C# используются XML-элементы, что позволяет определить структуру выходной документации. Одним из последствий использования этой функции является то, что в комментарии к документации можно добавить любой допустимый XML-код. Компилятор C# копирует эти элементы в выходной XML-файл. Несмотря на то что в комментариях (включая любой допустимый HTML-элемент) можно использовать любой допустимый XML-код, документирование кода рекомендуется по многим причинам.
Далее приводится ряд рекомендаций, распространенные сценарии использования и вопросы, которые нужно иметь в виду при работе с тегами XML-документации в коде C#. Несмотря на то что теги можно поместить в комментарии к документации, в этой статье описываются рекомендуемые теги для наиболее распространенных конструкций языка. Во всех случаях следует соблюдать следующие рекомендации:
XML-файл не предоставляет полную информацию о типе и членах (например, он не содержит никаких сведений о типе). Чтобы получить полную информацию о типе или элементе, используйте файл документации вместе с отражением для текущего типа или элемента.
Некоторые из рекомендуемых тегов можно использовать для любого элемента языка. Другие имеют более специализированное использование. Наконец, некоторые теги используются для форматирования текста в документации. В этой статье описываются рекомендуемые теги, упорядоченные по их использованию.
Комментарии документации не применяются к пространству имен.
Чтобы ввести в текст комментария документации угловые скобки, используйте для символов и > коды HTML и > соответственно. Это показано в следующем примере.
Общие теги
Члены документа
Тег следует использовать в комментариях к объявлению метода для описания возвращаемого значения.
следует использовать в комментариях к объявлению метода для описания одного из параметров такого метода. Чтобы задокументировать несколько параметров, используйте несколько тегов
отображается в IntelliSense, обозревателе объектов и веб-отчете по комментариям к коду.
Тег служит для указания возможных исключений. Этот тег может применяться к определениям методов, свойств, событий и индексаторов.
Форматирование выходных данных документации
создает абзац с двойным отступом. Используйте тег
, если хотите добавить в него один абзац.
Тег используется для указания нескольких строк кода. С помощью тега можно указать, что однострочный текст в описании необходимо пометить как код.
Повторное использование текста документации
Наследование XML-комментариев от базовых классов, интерфейсов и аналогичных методов. Использование inheritdoc позволяет обойтись без копирования и вставки одинаковых XML-комментариев и автоматически поддерживать их синхронизацию. Обратите внимание, что при добавлении тега к типу все члены также будут наследовать эти комментарии.
Тег позволяет задать ссылку на комментарии в другом файле, которые описывают типы и элементы вашего исходного кода. Включение внешнего файла является альтернативой размещению комментариев документации непосредственно в файле исходного кода. Помещая комментарии документации в отдельный файл, вы можете реализовать управление их версиями отдельно от версий исходного кода. В этом случае файл исходного кода может быть извлечен для изменения одним пользователем, а файл документации — другим. Тег использует XML-синтаксис XPath. Сведения об использовании тега см. в документации по XPath.
Создание ссылок и гиперссылок
Атрибут cref
Атрибут cref в теге XML-документации означает «кодовая ссылка». Он указывает, что текст внутри тега представляет собой элемент кода, например тип, метод или свойство. Средства создания документации, такие как DocFX и Sandcastle, используют атрибуты cref для автоматического создания гиперссылок на страницу, где документирован тип или член.
Атрибут href
Атрибут href означает ссылку на веб-страницу. Его можно использовать для прямой ссылки на интерактивную документацию по API или библиотеке.
Универсальные типы и методы
Тег следует использовать в комментариях к объявлению универсального типа или метода для описания параметра типа. Добавьте такой тег для каждого параметра типа универсального типа или метода. Текст для тега будет отображаться в IntelliSense.
Используйте этот тег, чтобы разрешить получателям файла документации форматировать слово определенным образом, например курсивным шрифтом.
Пользовательские теги
Все описанные выше теги распознаются компилятором C#. Тем не менее пользователь может определять собственные теги. Инструменты, такие как Sandcastle, обеспечивают поддержку дополнительных тегов (например, и ) и даже поддержку пространств имен документирования. Средства создания пользовательской или внутренней документации также можно использовать со стандартными тегами. Кроме того, поддерживается несколько выходных форматов — от HTML до PDF.
Восемь причин изучить PHPDoc
Часто встречаю вопрос о том, что же это за странные блоки комментариев постоянно генерируются в представлениях:
и перед всеми методами:
Что они обозначают и зачем они нужны? Это какой-то особый синтаксис объявления переменных в PHP или что?
Нет, это не совсем синтаксис PHP. А точнее, к самому PHP он никакого отношения не имеет и сам PHP интерпретатор его никогда не парсит. Это PHPDoc-блок, зародившийся ещё как JavaDoc и перешедший в PHPDocumentor
Пока мы не кодим так, как зажигают эти чуваки:
но попробуем разобраться.
Все эти вещи, судя по названию, как-то связаны с документацией. С неё и начнём.
Документация кода
Кому то стало лень писать документацию отдельно и он, вероятно, решил: «Отдельно документировать проект сложно и муторно. Нам же проще описывать прямо в комментариях каждый метод и класс. Давайте сделаем особый вид комментариев и при необходимости будем генерировать документацию по нему». И понеслось. В итоге придумали конструкции для объявления переменных, их типов и прочей метаинформации. И написали автоматический генератор, который парсит файлы в папке и генерирует HTML-файлы для каждого нашего класса.
Если посмотреть в API Reference и в код класса то увидим одно и то же:
Теперь понятно, как этот сайт так быстро меняется при каждом обновлении исходников. Оказывается, что он составлен не вручную, а автоматически сгенерирован по коду фреймворка.
Так что можем уже сформулировать первый бонус, который нам дают PHPDoc-блоки:
Применение первое: Возможность одной командой в консоли сгенерировать документацию с описанием всех классов, полей и методов своего проекта.
Но кроме этого чем он полезен в реальной жизни? Рассмотрим ещё несколько применений.
Виртуальные поля
В модели данных он пригодится для той же автогенерации полей по классу, но для чего его используют в представлениях, которые в документации не выводятся?
Оказалось, что формат PHPDoc оказался настолько удачным, что его встроенную поддержку наряду с JavaDoc подхватили практически все IDE вроде PhpStorm, NetBeans и прочие. В PHP нет встроенной типизации для чисел и строк, поэтому указывать тип в комментарии (чтобы не забыть) было бы полезно. Вот и нашему PHP-редактору оттуда тоже оказалось удобно парсить переменные и их типы.
Например, был класс без полей:
и непонятно что там, так как Yii2 берёт атрибуты из таблицы в базе данных. Автоподстановка видит только поля и методы из базового класса ActiveRecord :
А наши поля подчёркивает, при этом ругаясь, что их в объекте нет:
Можно заморочиться и написать плагин, который бы парсил поля из базы для каждой таблицы. Но это явно не лёгкий путь.
А давайте просто обозначим поля в PHPDoc-блоке (комментарии особой формы):
и редактору сразу станет понятно, какие поля теперь там есть для автоподстановки и какого они типа:
Теперь он в курсе наших дел и больше не ругается.
Или если в классе есть связи:
Но этих полей в классе нет. Всё работает через виртуальные методы и геттеры. Поэтому нам ничего не остаётся, как указать эти псевдополя и их типы явно:
Так что PHPDoc-блок перед классом может содержать полное перечисление того, чего в классе нет.
Применение второе: Указание псевдополей класса.
В примерах мы рассмотрели пока только поля. К псевдометодам подойдём позже.
Типы существующих полей
Помимо блока перед классом можно использовать и другие места.
Допустим, что у нас есть приватное поле _user у класса PasswordChangeForm :
редактор впадает в ступор и методы setPassword и save подсвечивает жёлтым, мотивируя это тем, что таких методов в этой переменной нет:
А если мы подскажем, что там у нас находится объект класса User :
то всё заработает как нам этого и хотелось.
Здесь мы аннотации @var передаём только тип. Но вообще ей можно передавать имя переменной, её тип или оба аргумента сразу.
Применение третье: Подсказка типов для имеющихся полей в классе.
Тип возвращаемого результата
Аналогично, если мы аннотацией @return укажем тип возвращаемого методом объекта:
И IDE будет учитывать оба случая.
Применение четвёртое: Подсказка типов аргументов и типа возвращаемого результата (при наличии) у процедур, функций, методов.
Переменные из ниоткуда
При этом для @var можно указать сначала тип, потом имя переменной:
В итоге автоподстановка, поиск и автозамена полей и методов объектов заработают для этих переменных автоматически.
Применение пятое: Обозначение переменных, каким-либо образом переданных извне.
Подмена типа
В итоге IDE по цепочке наследования подсмотрит аннотации метода ActiveRecord::find :
и склеит всё воедино.
В итоге IDE по строке:
поймёт, что из метода find должен вернуться экземпляр класса \yii\db\ActiveQuery и методы where и one будут вызываться уже у него:
Для правильной работы нам нужно явно указать тип переменной с помощью Doc-блока перед присваиванием:
или непосредственно перед использованием объекта:
Это удобно делать в циклах по различным выборкам:
Применение шестое: Подмена типа уже существующих переменных.
И вернёмся к методам.
Подключение примесей
Вначале мы рассмотрели виртуальные переменные. Теперь предположим, что к своему классу мы примешиваем любое поведение вроде:
Его достаточно добавить в метод behaviors :
и в представлениях выводить оригинал или превью:
и все методы getImageFileUrl и прочие будут доступны в автоподстановке.
В таком случае вместо примешавания всего класса поведения с помощью @mixin мы можем просто добавить определение только пары нужных нам виртуальных методов:
Применение седьмое: Определение псевдометодов класса.
Программирование с аннотациями
Помимо простой работы с PHPDocumentor некоторые системы пошли дальше и придумали для своих целей собственные виды аннотаций. И некий программный код через рефлексию парсит эти данные. Взять хоть первый попавшийся пример с сайта StackOverflow:
В итоге этот подход нашёл новое применение. Например, в Symfony Framework с помощью собственных аннотаций (помимо конфигурации в YAML или XML-файлах) с использованием пакета doctrine/annotations можно конфигурировать те же сущности прямо в коде:
или ту же маршрутизацию контроллеров:
И фреймворк легко парсит эти данные и кеширует в простые PHP-массивы, чтобы не парсить их каждый раз снова и снова.
Также в уроке по тестированию мы рассматривали аннотации вроде @group и @dataProvider для тестов в пакете PHPUnit.
Этот подход уже мало связан с оригинальным PHPDoc, так как просто использует его идею. Но при этом друг другу никто не мешает и можно спокойно использовать различные ключи вместе:
Многим такой подход с конфигурированием аннотациями в Symfony не нравится, так как он нарушает принцип единой ответственности, смешивая программный код и конфигурацию в одном файле. Так что используйте по своему усмотрению.
Восьмая причина: Появление программных систем с поддержкой специфических аннотаций.
Пока на этом всё. Если в комментариях приведут и другие примеры использования, то дополню статью.
И в итоге
С помощью PHPDoc-блоков можно легко «научить» свой редактор понимать вас с полуслова и всегда знать, какие переменные и каких типов используются в каждой строчке кода.
После этого не будет проблем с автоподстановкой, опечатками, несовпадениями типа, неопределёнными переменными, с автоматическим переименованием полей или методов любого класса и прочим автоматическим рефакторингом.
Дружите со своей IDE и она облегчит вашу жизнь.
Ну и, вроде, праздник скоро, так что не спалите ёлку:
Не пропускайте новые статьи, бонусы и мастер-классы:
В прошлой части мы немного изменили структуру нашей системы. Фактически это были банальные операции по переносу файлов и частей кода с места на место. А сейчас добавим что-то новое. В комментариях предложили вычищать из базы пользователей, не активировавших свой адрес при регистрации. Рассмотрим. как это можно осуществить.
В нашем проекте хоть и есть модульная структура, но она пока модульная не полностью. Предыдущие главы были немного дополнены и изменены. Если вы следили за обновлениями в комментариях, то могли заметить, что мы немного исправили наш проект. Сегодня мы как раз рассмотрим эти исправления.
В этот раз порассуждали о понятиях и реализациях различных подходов к авторизации, аутентификации и контроле доступа на основе ролей в Yii2. Рассмотрели нюансы, сравнили друг с другом различные подходы к реализации RBAC.
Самая объёмная тема среди предложенных завершена. Выкладываю исправленную и дополненную запись вебинара-скринкаста о тестировании c PHPUnit и Codeception. Добавлены и доработаны примеры кода, пункты про аннотации, фикстуры, анализ покрытия, Faker, про установку всего через Composer и другие нюансы.
Здравствуйте!
Подскажите, пожалуйста, где описывать собственные компоненты, чтобы PhpStorm не подчёркивал их при вызове Yii::$app->myComponent->myMethod
Спасибо.
В простейшем случае можно получить компонент явно:
Это понятно, но это не удобно.
Тогда придумайте другой способ.
Для этого в нашем проекте мы создали файлик codeAssist.php следующего содержания:
как использовать ваш файл?
Просто положить в папку с проектом. У нас он лежит здесь:
backend/runtime/codeAssist.php
А как борться теперь с конфликтом вроде multiple definition for class?
Ну, если речь о phpStorm’е идет, то кликаем правой кнопкой по vendor/yiisoft/yii2/Yii.php и выбираем в меню «Mark as Plain Text»
Да, но после пересборки vendor все заново делать
Для этого можно унаследовать свой Application, в котором в виде хинтов @property указать свои компоненты. Не знаю, на сколько это целесообразно, но есть такой рецепт. 🙂
Возможно, там найдется что-нибудь интересное.
Было бы ещё полезно узнать как автоматически генерировать API documents с возможностью пробовать в работе методы
А вот как scopes прокомментировать, что бы ide потом подставила ключи массивов, как функцию или так не реально сделать?
Забыл добавить что речь идет про Yii1)
А вот как scopes прокомментировать, что бы ide потом подставила ключи массивов, как функцию или так не реально сделать?
Также через @method у класса модели.
А все понял спасибо)
Интересно.
Но я пользуюсь sublime text 3, есть для этого редактора такая возможность?
Что мешает проверить?
Спасибо за статью, как всегда замечательно! «@mixin» я как-то пропустил, теперь буду использовать)
Заметил небольшие опечатки в нескольких местах: в комментарии «$post», а в коде «$model».
А что сделать чтоб не было подсветки серым «Field accessed via magic methot»
В первом комментарии уже, вроде, ответили.
А как можно описать анонимную функцию, интересует конкретно конструкция use, например:
Тогда пропишите явно.
вот этот случай можно как-то обрулить через описание единоразово в моделе(возможно через переопределение чего-то). но я забыл как и нигде не могу найти( но я точно видел довольно простое решение, чтобы не писать это каждый раз.
Как прописать эти конкретные поля в аннотациях, чтобы IDE их предлагала для автоподстановки?
В своих новых уроках, Вы не используете phpdoc, но это скорее в угоду скорости разработки.
Каких то холиваров по этому поводу я нигде в интернете не видел, в общем интересно Ваше мнение.
В PHP 7 появилась возможность указания скалярных типов аргументов, а сейчас в 7.4 и описание типов полей, поэтому простые блоки:
уже не нужны, так как это уже описывается непосредственно типами:
Сейчас PHPDoc остаётся нужен только для особых ситуаций вроде этой:
Здесь мы указываем, что это array именно из постов Post[] и что этот метод кидает исключение DomainException.
В языке Java это всё указывается типами:
а в PHP такого ещё нет.
Как же мы жили раньше без этого?) На сегодня необходимо знать такое кол-во технологий, подходов, парадигм, языков. каждая из которых обновляется раз в пару месяцев что просто физически невозможно следовать всем этим стандартам. Вникайте в это Doc только если вам заплатят деньги на фирме за это, или самому интересно. Я конечно не работал в гугле, но в тех компаниях где был, об этом даже не говорили (хотя в одной мы написали собственный фреймворк, который и кормит нас всех). Я вообще считаю что на документацию надо выделять отдельного человека, или доплачивать.
В MVC модели разделения данных во вьюшках, особенно когда их несколько и одна в другой подключается, теряется связь между переменными. Они переименовываются и не понятно какая что означает. Когда вверху файла объявишь через /** @var */ тип либо какую-то подсказку даёшь, как эта переменная формировалась, сразу же становится всё понятно и не надо возвращать своё внимание к самым истокам формирования и передачи переменной, чтобы найти все её концы во вьюшках.
Преимущество просто очевидное. Предполагаю, что вы не работает в IDE (PhpStorm либо ему подобных), иначе данного вопроса скорее всего просто бы не возникло.
То yii, то ларавель. документация еще существует для тестов. самое важное и не упомянули.