Документирование ассоциативных массивов в PHPDoc

Если вы используете стандарт PHPDoc для документирования своего кода на PHP (а вам не мешало бы это делать), то наверняка рано или поздно задавались вопросом, а как же, собственно, документировать структуру массива, обязательные и необязательные ключи, типы значений, входящих в массив и т.п. Ну то есть с совсем простыми массивами понятно, что делать:

@param array $some_array

или подробнее:

@param int[] $some_array

Но что, если, например, аргумент вашей функции — сложный ассоциативный массив, и вам непременно надо проинструктировать коллегу (или себя самого в будущем), какие именно индексы в нем ожидаются. Оказывается, стандартных путей это сделать просто нет. Порывшись в StackOverflow, Quora и на сайтах, обсуждающих PSR и PHPDocumentor, обнаружил, что программисты каждый раз «изобратют велосипед», и в общем-то все варианты сводятся к разным вариантам индентации, а сама структура массива описывается просто перечислением ключей и, иногда, их типов следом за стандартным определением массива через @param. Например, так (ответ на StackOverflow):

/**
* Holds configuration settings for each field in a model.
* Defining the field options
*
* array['fields'] array Defines the fields to be shown by scaffolding.
*     [fieldName] array Defines the options for a field, or just enables the field if array is not applied.
*         ['name'] string Overrides the field name (default is the array key)
*         ['model'] string (optional) Overrides the model if the field is a belongsTo associated value.
*         ['width'] string Defines the width of the field for paginate views. Examples are "100px" or "auto"
*         ['align'] string Alignment types for paginate views (left, right, center)
*         ['format'] string Formatting options for paginate fields. Options include ('currency','nice','niceShort','timeAgoInWords' or a valid Date() format)
*
* @param array $arr (See above)
* @return Object A new editor object.
**/

В данный момент открыто обсуждение в проекте развития PHPDocumentor, но к единому знаменателю пока так и не пришли. Было предложено, в частности, использовать вложенные описания типов:

@type array {
    @type integer $keyName 
}

или определять новые структуры данных в PHPDoc на уровне файла, к которому они относятся, и затем в качестве типа указывать эту структуру:

 @type-definition object MyDefinition {
      @property integer $myProperty
 }

Обсуждение, однако, до сих пор открыто.

Другие варианты, предложенные на Stackoverflow:

@param array $config [key1=>int, otherKey=>string]

и простое описание структуры массива в тегах <code> для удобочитаемости:

/**
* Form the array like this:
* <code>
*     $array = array(
*     'id' => 'foo', // the id
*     'class' => 'myClass', // the class
* );
* 
* </code>
*
* @var array[string]string 
*/

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

Лично я пришел к следующему варианту с учетом его красивого отображения в IDE PHP Storm (вся отбивка табами, строки @param и show_id там отстоят друг от друга на один таб).

/**
 * Returns a decorated (with some options) list of the subgenres of the current genre
 *
 * @param array $options
 *  show_id bool false whether to show ids in square braces or not<br/>
 *  show_sort bool false whether to prepend a genre name with a sort number
 * @return string
 */
public function getDecoratedChildrenList($options = array())
{
   $default_options = array(
      'show_id'=>false,
      'show_sort'=>false
   );
   $options = array_merge_recursive($default_options, $options);
   //...

2 комментария

  1. Проблема в том, что потом IDE во всех эти вариантах сливает развёрнутое описание твоего массива в одну строку со своими переносами и это плохо читается.

Оставить комментарий

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.