Документирование PHP кода. DocBlock комментарии

Хочу рассмотреть принцип документирования программного PHP кода, основанный на DocBlock (DocBlock comments). Многие называют его стандартом, хотя каких-то авторитетных источников, подтверждающих это, я не нашел. Тем не менее, данный формат комментариев распространен во многих языка. Насколько я понимаю, пришел он из Java и по своему принципу наследует Javadoc. Он прекрасно поддерживается и интерпретируется средами разработки. Также существует немало решений, позволяющих автоматически генерировать документацию на основе таких комментариев.

DocBlock – это многострочный комментарий, требующий соблюдения определенного синтаксиса. В PHP данный способ более известен под другим именем – phpDoc. Оно происходит от названия утилиты phpDocumentor, предоставляющей возможность создавать страницы документации автоматически. Результат ее работы очень похож на официальную документацию PHP.

О пользе написания комментариев написано немало. Обычно призывы основаны на необходимости заботиться о тех, кому придется работать с вашим кодом в дальнейшем. Безусловно, я с этим согласен, но считаю это очень плохой мотивацией. Люди эгоистичны и зачастую действуют только в своих собственных интересах, что совершенно нормально.

Я хочу привести ряд аргументов, которые, возможно, смогут убедить в том, что хороший комментарий несет пользу прежде всего нам самим. phpDoc блоки позволяют увеличить не только читаемость существующего кода, но и ускорят написание нового за счет использования возможностей IDE.




Синтаксис phpDoc

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

/**
 * @имя_дескриптора значение_директивы
 * @еще_дескриптор
 *
 */

Наверное, стоит заметить, что каждая строка внутри блока должна начинаться с символа *. Именам дескрипторов предшествует знак @.

phpDoc может описывать не только отдельные участки кода, но и весь файл скрипта, располагаясь в самом начале файла. Такой блок называется заголовочным.

Ниже предлагаю список дескрипторов phpDoc и мои комментарий к ним.

Дескриптор Значения/Пример Описание
@abstract none Описывает абстрактные классы, методы или свойства
@access private/protected/public Указывает на модификатор доступа свойства или метода класса.
@author @author Oleg Murashov Имя автора кода. phpDocumentor будет искать текст между угловыми скобками (< >). Если такая конструкция будет найдена и ее формат будет соответствовать e-mail адресу, то она будет преобразована в соответствующую ссылку.
@category @category Zend Имя категории, в которую объединены несколько пакетов.
@copyright Copyright (c) 2005-2011 Company Информация, указывающая на правообладателя кода.
@deprecated @deprecated 1.7 Дескриптор указывает на то, что код устарел. В качестве значения дескриптора указывается версия, начиная с которой код считается устаревшим.
@example @example /path/example.php описание Указывает путь к файлу, содержащему пример использования кода. phpDocumentor опубликует пример, подсветив синтаксис и пронумеровав строки.
@final none Дескриптор отмечает методы или свойства, которые не могут быть перегружены в дочерних классах. Также может быть отмечен класс, который не должен быть наследован.
@filesource none Дескриптор может быть использован только в заголовочном комментарии. В других местах она игнорируется. Указывает phpDocumentor’у на необходимость вывести исходный код текущего файла, подсветить синтаксис и пронумеровать строки.
@global @global datatype описание Дескриптор для декларации глобальных переменных. Для понимания того, как верно использовать данную директиву, лучше всего обратиться к соответствующей документации.
@ignore none Сообщает phpDocumentor’у, что данный код не следует включать в лист документации
@internal @internal комментарий Значение дискриптора не будет добавлено в файлы документации. Удобно, если нужно оставить комментарий только для тех, кто работает с кодом
@license @link http://www.example.com/License.txt GPL License Добавляет ссылку на лицензию, под которой распространяется код
@link @link http://www.example.com Текст ссылки Дает возможность добавить ссылку в к любому документируемому коду.
@method @method returntype описание Используется для описания магического метода __call().
@name @name $globalvariablename Дает возможность сослаться на краткое имя глобальной переменной, объявленной с помощью @global
@package @package Zend_Pdf Указание имени пакета, в который входит данный программный код (файл). Используется в заголовочном блоке файла или в блоке комментариев класса.
@param @param datatype1|datatype2 $paramname описание Дескриптор описывает входные параметры для функций и методов классов. Содержит информацию и типе данных параметра и его описание.
@property
@property-read
@property-write
Дескрипторы описывают свойства класса, которые могут быть записаны или прочитаны с помощью магических методов __set() и __get(). Если свойство доступно для чтения и записи, необходимо использовать директиву @property. Если только для чтения или только для записи, то @property-read или @property-write соответственно. Используются только в блоке описания класса.
@return @return datatype1|datatype2 описание Используется для описания данных, возвращаемых функцией или методом класса. Синаксис схож с дискриптором @param. Если в качестве типа будет указано имя класса, phpDocumentor автоматически создаст ссылку на данный класс.
@see @see … Дескриптор предлагает обратиться к другому, уже существующему докблоку. Например, может быть использован при документировании метода, класс которого имплементирует интерфейс, где уже существует полноценный докблок. Позволяет избежать дублирования комментариев.
@since @since v 0.7 Указывает на версию пакета/класса, с которой комментируемый элемент стал доступен. Например, при описаниии метода, который появился только в какой-то версии класса, можно указать эту версию.
@static none Маркирует статические методы или свойства класса
@subpackage @subpackage Name Используется для объединения нескольких пакетов в один раздел документации. Игнорируется, если нет дескриптора @package. Как и @package, помещается в заголовочном блоке комментариев.
@todo @todo Something Можно описать будущие возможные изменения кода
@throws @throws MyException Указывает тип исключения, который может быть возвращен участком кода
@var @var string Указывает тип свойства класса
@version @version Version 1.1 Текущая версия реализации документируемого кода.

Дескрипторы @access, @final и @abstract были актуальны в PHP 4, но сейчас их можно не использовать, так как они потеряли актуальность с появлением модификаторов доступа и ключевых слов final и abstract.

Каждый docBLock делится на несколько секций:

  • заголовок;
  • описание;
  • список дескрипторов.

Разделителем для секций служит пустая строка.

Примеры использования phpDoc комментариев

Я не хочу приводить синтетические примеры, поэтому заимствую код из популярного фреймворка Zend Framework, который, как мне кажется, имеет самые толковые и подробные блоки комментариев.

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

Использование дескриптора @see

/**
 * @see Zend_Acl_Resource_Interface
 */
require_once 'Zend/Acl/Resource/Interface.php';

Пример блока комментариев для метода класса

/**
 * Removes "deny" restrictions from the ACL
 *
 * @param  Zend_Acl_Role_Interface|string|array     $roles
 * @param  Zend_Acl_Resource_Interface|string|array $resources
 * @param  string|array                             $privileges
 * @uses   Zend_Acl::setRule()
 * @return Zend_Acl Provides a fluent interface
 */
public function removeDeny($roles = null, $resources = null, $privileges = null)
{
    return $this->setRule(self::OP_REMOVE, self::TYPE_DENY, $roles, $resources, $privileges);
}

Свойство класса

/**
 * Role registry
 *
 * @var Zend_Acl_Role_Registry
 */
protected $_roleRegistry = null;

А вот один из примеров подсказок (Eclipse code assist), которые может предлагать среда разработки, в данном случае Eclipse.

Eclipse code assist

Также среда разработки может выводить подсказки, основанные на docBlock. Например, подсказка, появляющаяся при наведении на имя метода Zend_Acl_Role_Registry::add().

Eclipse code tooltip

Комментарии (1)

  1. Есть класс с вспомогательными protected и public методами, который используется в основном классе посредством trait примеси. Как импортировать в основной класс всю автоподсветку из trait класса, чтобы во вне видились также публичные методы, а внутри класса, IDE не ругалась на приватные методы?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *