Когда надоело запоминать ключи массивов и хочется пользоваться подсказками любимого редактора кода на помощь приходит PHPDoc и немного смекалки.
Недавно я очень близко познакомился с TypeScript и познал всю прелесть строгой типизации. Как же это приятно, когда редактор кода подсказывает тебе какие поля есть в объекте и что ты с ними можешь сделать!
В чем проблема?
Я работаю с CMS Битрикс и приходится иметь дело с массивами разной формы и содержания, запоминать все ключи или искать их в документации. Это занимает драгоценное время.
Решение:
Первым делом на ум приходит использовать PHPDoc, но тут появляется проблема:
/**
* int[]
* array
* array<string>
*/
Нельзя прописать многомерный массив так, чтобы подсказывал редактор кода. Все найденные мной варианты не работают в VSCode и PhpStorm.
Недолго погуглив я нашёл вариант, который заработал только в VSCode.
/**
* @var array $arr $arr
* @var array $arr['fields']
* @var array $arr['fields']['fieldName']
* @var array $arr['fields']['fieldName']['name']
* @var array $arr['fields']['fieldName']['model']
* @var array $arr['fields'][fieldName]['width']
* @var array $arr['fields'][fieldName]['align']
* @var array $arr['fields'][fieldName]['format']
* @var array $arr['fields'][fieldName]['title']
* @var array $arr['fields'][fieldName]['desc']
* @var array $arr['fields'][fieldName]['readonly']
* @var array $arr['fields'][fieldName]['type']
* @var array $arr['fields'][fieldName]['options']
* @var array $arr['fields'][fieldName]['editor']
* @var array $arr['fields'][fieldName]['default']
**/
$arr = [
'fields' => [
'fieldName' => []
]
];
В таком случае среда подсказывает какой ключ можно выбрать:
Для PhpStorm есть плагин deep-assoc-completion, он требует описания массива в определённом формате:
/**
* @var array $arr = [
* 'fields' => [ // Defines the feilds to be shown by scaffolding
* $anyKey => [
* 'name' => 'sale', // Overrides the field name (default is the array key)
* 'model' => string, // (optional) Overrides the model if the field is a belongsTo associated value.
* 'width' => '100px', // Defines the width of the field for paginate views. Examples are "100px" or "auto"
* 'align' => 'center', // Alignment types for paginate views (left, right, center)
* 'format' => 'nice', // Formatting options for paginate fields. Options include ('currency','nice','niceShort','timeAgoInWords' or a valid Date() format)
* 'title' => 'Sale', // Changes the field name shown in views.
* 'desc' => 'A deal another person that results in money', // The description shown in edit/create views.
* 'readonly' => false, // True prevents users from changing the value in edit/create forms.
* 'type' => 'password', // Defines the input type used by the Form helper
* 'options' => ['option1', 'option2'], // Defines a list of string options for drop down lists.
* 'editor' => false, // If set to True will show a WYSIWYG editor for this field.
* 'default' => '', // The default value for create forms.
* ],
* ],
* ]
*/
$arr=[
'fields' => [
'0' => [
'model' => 2
]
]
];
В таком случае среда подсказывает ключи:
Остаётся одна проблема, если мы хотим таких подсказок, нам нужно делать подобное описание в каждом файле, где есть наш массив. Особенно актуально для Битрикса.
Моё решение:
Редактор кода хорошо индексирует объекты, так почему бы нам не привести массив к объекту и описать его?! Но как описать объект без класса, ведь PHPDoc в этом тоже помощник?
Мы можем создать класс, в котором опишем все нужные нам поля. И вот наш редактор уже подсказывает нам.
Хорошо, а дальше? Многомерные массивы мы можем описать так же как описываем интерфейсы в TS. Либо выносим вложенный массив в отдельный класс:
Либо прописываем в конструкторе текущего класса:
Обратите внимание, конструктор делаем приватным, чтобы нам не мешался, а вложенному полю обязательно создаём описание. Но PHPStorm его не поймёт.
Резюме
Вариант конечно запарный, но люди, пишущие на TS и так это уже давно делают. Если есть вариант получше, буду рад рассмотреть. И самое главное, смысл не в том, что так надо делать всегда, а в том, что если других вариантов нет (ограничены по времени и т.д. и т.п.), то можно применить эту технологию.