Как в PHP из массивов сделать объекты с подсказками?

Когда надоело запоминать ключи массивов и хочется пользоваться подсказками любимого редактора кода на помощь приходит 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' => [] ] ];

В таком случае среда подсказывает какой ключ можно выбрать:

Как в PHP из массивов сделать объекты с подсказками?

Для PhpStorm есть плагин deep-assoc-completion, он требует описания массива в определённом формате:

/** * @var array $arr = [ * 'fields' => [ * $anyKey => [ * 'name' => 'sale', * 'model' => string, * 'width' => '100px', * 'align' => 'center', * 'format' => 'nice', * 'title' => 'Sale', * 'desc' => 'A deal another person that results in money', * 'readonly' => false, * 'type' => 'password', * 'options' => ['option1', 'option2'], * 'editor' => false, * 'default' => '', * ], * ], * ] */ $arr=[ 'fields' => [ '0' => [ 'model' => 2 ] ] ];

В таком случае среда подсказывает ключи:

Как в PHP из массивов сделать объекты с подсказками?

Остаётся одна проблема, если мы хотим таких подсказок, нам нужно делать подобное описание в каждом файле, где есть наш массив. Особенно актуально для Битрикса.

Моё решение:

Редактор кода хорошо индексирует объекты, так почему бы нам не привести массив к объекту и описать его?! Но как описать объект без класса, ведь PHPDoc в этом тоже помощник?

Мы можем создать класс, в котором опишем все нужные нам поля. И вот наш редактор уже подсказывает нам.

Как в PHP из массивов сделать объекты с подсказками?

Хорошо, а дальше? Многомерные массивы мы можем описать так же как описываем интерфейсы в TS. Либо выносим вложенный массив в отдельный класс:

Как в PHP из массивов сделать объекты с подсказками?

Либо прописываем в конструкторе текущего класса:

Как в PHP из массивов сделать объекты с подсказками?

Обратите внимание, конструктор делаем приватным, чтобы нам не мешался, а вложенному полю обязательно создаём описание. Но PHPStorm его не поймёт.

Резюме

Вариант конечно запарный, но люди, пишущие на TS и так это уже давно делают. Если есть вариант получше, буду рад рассмотреть.

55
23 комментария

Не хотелось вас оскорблять, но битрикс ненавидят как раз из за таких как вы =))
Как вы делаете в типизацию (которая нивелирует огромное количество ошибок еще на моменте интерпритации) с вашими многомерными массивами?

У битрикса вполне удобоваримый фреймворк со своими сущностями и коллекциями, которые в том числе можно расширять. В данном случае работает поговорка "Можно вывезти девушку из деревни, а вот деревню из девушки не вывести никогда", как будто битрикс заставляет заниматься всей этой ерундой и страдать от этого.

PS. Работаю с битриксом в больших командах на огромных (миллионых по аудитории) проектах, многомерных асоциативных массивов практически не используем и все счастливы, везде классы, контроллеры, модельки, сервисы и прочие радости и где то там глубоко под этими абстракциями запрятано ядро битрикса.

9

🤣 А я знаю такой анекдот:
Не зли меня, а то заболеешь.
Чем?
Переломом челюсти и сотрясением мозга.
Будьте осторожны так, как первую уже получили в виде дизлайка.

Бро, а огромные, сколько в секунду нагрузка?)

1. Есть поддержка описательного синтаксиса массивов в PHPStorm https://blog.jetbrains.com/ru/phpstorm/2021/08/phpstorm-2021-2-release/#array-shapes
2. Поздравляю, вы придумали сериализатор, который даже работает и отвечает вашим требованиям, но результат все равно выглядит странно. Предлагаю рассмотреть возможность использовать готовые библиотеки (https://jmsyst.com/libs/serializer) для решения ваших проблем.

2

1. Это хорошо, что есть поддержка в PHPStorm, не все им пользуются. Но есть проблема, если вы используете массивы часто и много, а особенно если они большие, ваш код будет изобиловать комментариями, описывающими структуру массива. Возьмите штатный компонент битрикса и несколько шаблонов для него и получится, что в каждом шаблоне вам придётся описывать структуру этих массивов, а если там есть result_modifier.php и component_epilog.php, то ещё по разу в каждом файле. Такое себе решение, как по мне.
2. За совет спасибо, изучу.

Я не специалист в этой области и скажу честно, что очень заинтересовала статья.
Спасибо автору за работу.
Только без дизлайка.😊

2

Комментарий недоступен

1