Пых – Telegram
Пых
8.28K subscribers
260 photos
14 videos
6 files
566 links
Блог Валентина Удальцова о разработке на PHP.

Хобот @phpyhobot
https://youtube.com/@phpyh
https://vkvideo.ru/@phpyh
https://news.1rj.ru/str/isPHPdying

Статистика: https://news.1rj.ru/str/INOTAROBOT?start=st1219340804

Для связи используйте личные сообщения канала.
Download Telegram
Класс должен быть либо абстрактным, либо финальным.

Мотивация:
- https://www.tomasvotruba.cz/blog/2019/03/28/how-to-mock-final-classes-in-phpunit/;
- https://ocramius.github.io/blog/when-to-declare-classes-final/.

Кнуты и плётки:
- в PHP-CS-Fixer включаем final фиксер;
- для PHP CodeSniffer ставим нюхача https://github.com/matthewbdaly/abstract-or-final-sniff.

Как мокать:
- если над классом есть интерфейс, то мокать надо его, а не имплементацию;
- если это Entity или ValueObject, то лучше не мокать, а работать с полноценным экземпляром;
- в крайнем случае есть https://github.com/dg/bypass-finals. Как правильно его пристегнуть к PHPUnit: https://www.tomasvotruba.cz/blog/2019/03/28/how-to-mock-final-classes-in-phpunit/#4-single-hook.
1
Надеюсь, все знают, что начиная с Symfony 4.1 можно инлайнить конфигурацию роутов в путь.
То есть вместо
@Route("/studies/{studyId}", requirements={"studyId"="\d+"}, methods={"PUT"})
писать
@Route("/studies/{studyId<\d+>}", methods={"PUT"})


Если вдруг нет, читайте новость от 22 марта прошлого года: https://symfony.com/blog/new-in-symfony-4-1-inlined-routing-configuration. Или ищите в документации https://symfony.com/doc/current/routing.html по слову inline.

Но что если у нас UUID? Не указывать же каждый раз этот гигантский Regex!
@Route("/studies/{studyId<[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}>}", methods={"PUT"})


Тут нам приходят на помощь параметры контейнера.
parameters:
regex.uuid: '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'

@Route("/studies/{studyId<%regex.uuid%>}", methods={"PUT"})


Подробнее тут: https://symfony.com/doc/4.2/routing/service_container_parameters.html (страница доступна только для 4.2, потому что документацию сейчас реструктуризируют).
Записали на Пятиминутке PHP два подкаста.

https://5minphp.ru/episode72/ про
- прошедшую SymfonyCon Amsterdam и мой доклад,
- результаты Hack Day,
- Symfony Messenger,
- события предметной области,
- Symfony 5/6.

https://5minphp.ru/episode73/ про
- SymfonyCloud,
- более удобную разработку с Docker на маке,
- надежную отправку/доставку сообщений с RabbitMQ (https://vimeo.com/111998645),
- статический анализ кода при помощи Psalm и других инструментов.

Всех приглашаю послушать!
Чтобы быстро и красиво оформлять консольные команды в привычном стиле Symfony, рекомендую использовать поставляемый с библиотекой Symfony\Component\Console\Style\SymfonyStyle. У него куча хелперов почти на все случаи жизни.

https://symfony.com/doc/current/console/style.html
Обновляем symfony/flex до 1.6.0 и запускаем команду composer recipes!
Она покажет все доступные рецепты и возможные обновления.

https://github.com/symfony/flex/pull/562

#Symfony #Flex
Отчаянно рекомендую свежий доклад @ocramius про тестирование и обеспечение качества кода.

https://www.youtube.com/watch?v=8rdTSYljts4

Из него вы узнаете:
- про график "этап разработки / цена ошибки" (https://youtu.be/8rdTSYljts4?t=340),
- почему отдел QA не нужен (https://youtu.be/8rdTSYljts4?t=526),
- про архитектуру и Architecture Decision Record (https://youtu.be/8rdTSYljts4?t=990),
- почему важна типизация (https://youtu.be/8rdTSYljts4?t=1771),
- про Psalm (https://youtu.be/8rdTSYljts4?t=1844),
- о "Пирамиде Маслоу" проекта (https://youtu.be/8rdTSYljts4?t=3357),
- про инструменты тестирования и анализа кода.

Наверняка что-то забыл или не отметил, лучше смотрите целиком.

#PHP #Testing #QA
И в продолжение темы тестирования. Доклад про то, почему интеграционные тесты — жульничество. Почему их количество всегда растет, а качество проекта при этом падает. Как правильно писать изолированные (юнит-) тесты и как тестировать контракты.

Намеренно не расписываю тайм-коды, потому что этот доклад представляет собой цельное повествование от проблемы до решения.

https://vimeo.com/80533536 или https://www.youtube.com/watch?v=VDfX44fZoMc

#Testing #TDD
В недавно вышедшей Symfony 5.0 появилась компонента String.

Актуальный обзор в сегодняшней новости: https://symfony.com/blog/new-in-symfony-5-0-string-component.

Документация: https://symfony.com/doc/current/components/string.html.
Документация по использованию в Twig: https://twig.symfony.com/doc/2.x/filters/u.html.

Наглядная презентация идеи от автора библиотеки Николаса: https://speakerdeck.com/nicolasgrekas/symfony-string-flexible-handling-of-unicode.

#PHP #Symfony
Помог обновить https://github.com/dunglas/doctrine-json-odm для совместимости с Symfony 5. Кто юзает этот замечательный пакет, апайте до 1.0.1.

Как правило, такие PR тривиальны и занимают до получаса времени. Позитивный сценарий:
• форкаем и клонируем репозиторий;
• добавляем в composer.json к пакетам symfony/* версии || ^5.0 ;
composer update;
• запускаем локально тесты либо сразу создаем PR и ждем результатов CI;
• попутно могут возникнуть какие-то мелочи, смотрите мой https://github.com/dunglas/doctrine-json-odm/pull/83.

Призываю вас участвовать в обновлении используемых вами пакетов. Это элементарный способ законтрибьютить, поближе познакомитьсся с кодом и авторами да и просто получить 🟩 в карму на GitHub.

#OSS #Contributing #Symfony
Мета-вопросы а-ля "Можно спросить?" или "Ребят, есть вопрос по %technology%" усложняют общение в онлайне. Спрашивайте сразу по делу. Это не про вежливость — это про уважение к чужому времени. Нет глупых вопросов, есть бесполезные предисловия.

https://nometa.xyz/
Крутая статья про контринтуитивный парсинг JSON. Ценность её не только в исследовании причины невалидности выражения [01], но и в ёмком экскурсе в парсеры на примере формата, который знают все.

Я был бы счастлив прочитать такую статью несколько лет назад, перед тем как написать свой первый кастомный тег для Twig и DQL функцию для Doctrine ORM.

https://nullprogram.com/blog/2019/12/28/
Внезапно узнал, что можно передавать массив искомых значений в аргументе $criteria метода EntityRepository::findBy(). Он автоматически будет преобразован в выражение IN(...).

Пример:
$em->getRepository(Question::class)->findBy([
'id' => [
'82f06c7f-7513-464d-972d-857fb169f86a',
'25ee6a8d-72b8-449f-9409-cdb545b28f5b',
],
]);


В документации можно найти на странице https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-objects.html#by-simple-conditions по фразе If you pass an array of values.

Надеюсь, в отличие от меня вы и так это знали и не создавали почем зря query builder.
Однако, если вы хотите проиндексировать результирующий массив идентификаторами, без query builder не обойтись: потребуется метод indexBy.