В мире PHP #1

В мире PHP #1

FartTime

⬅️ предыдущая часть

Мутационное тестирование

Напомню, что мутационное тестирование — это отличный способ убедиться в том, что написанные тесты – говно и ничего не тестируют даже при 100% покрытии.

Infection

Infection теперь поддерживает кастомные мутаторы. Вероятно, это будет полезно только авторам каких нибудь популярных пакетов. Для меня же это просто повод упомянуть крутой инструмент.

Pest

В PEST 3 будет мутационное тестирование. Нуно пишет, что наговнокодили его с нуля, а не обернули infection/infection.

Сам я кое где использую pest из-за плагина arch, чтобы в CI проверять не забыл ли убрать все trap()/dump()/etc из кода (пример). Если мутации в нём будут удобнее инфекций или покрывать больше кейсов, то их тоже буду использовать.

В базе pest — это враппер вокруг phpunit с некоторыми надстройками и своими плагинами. Несмотря на то, что по команде vendor/bin/pest запустятся и тесты phpunit, использовать его я всё-таки рекомендую отдельно и только в тех местах, которые не покрываются phpunit'ом.

Вот почему:

  • Не работают фичи типа runInSeparateProcess.
  • На вкус и цвет, как говорится, но pest предлагает отвратительный синтаксис юнитов:
Скуфу не нравится синтаксис песта
  • Плохо поддерживается IDE. Наличие плагина не спасет: запустить какой-то один тест из интерфейса PHP Storm не получится.
Даже прыгнуть к сорцам не предлагает


В общем, если ты не скуф, тебе нравится розовый или просто нужны какие-то фичи песта, вот короткий гайд, чтобы не наступать на грабли:

  • Раскидать тесты по папкам.
  • Сделать копию конфига phpunit.xml.dist, обозвать pest.xml.dist и удалить из него всё лишнее. Да, это обособленный конфиг для pest, иначе он нам всё испортит.
  • Разделить на testsuites . Например phpunit будет запускать Feature и Unit тесты, ведь в этом плане он нас полностью устраивает:
phpunit.xml.dist
  • Pest-specific тесты (Arch) закинуть в pest.xml.dist.
  • phpunit запускаем как обычно, а pest с указанием отдельного конфига:
./vendor/bin/pest --color=always --configuration pest.xml.dist

Дополнительно: пример arch тестов для симфы.

Ещё скоро в песте появятся пресеты для arch тестов.


Серверы

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


В RoadRunner, как обычно, открытых багов нет. Они фиксятся ещё до появления или в течение нескольких миллисекунд после.

Это настолько нравится пользователям, что один из них нахреначил статью Scaling PHP Applications with RoadRunner аж на 60 страниц (или 90 экранов). Что самое ужасное — на весь этот объём нет ни одного мемчика. Статья коротко о том, как с нуля интегрироваться в RoadRunner (считай свой фреймворк Spiral на минималах), и о приятном бонусе в виде срезания бутстрапа в неумирающем приложении.


В это время Swoole во всю пилят версию 6 и уже вмержили поддержку multi thread, даже доку подготовили. Самое время почитать введение в Swoole (и асинхронный PHP) и в стиле хорошо/плохо посмотреть на фичи свулятинки.


Temporal

Недавно SDK PHP релизнулся в версии 2.9.0 (там было ещё 5 небольших релизов, но речь не о них). Это очень классное обновление, направленное на улучшение клиентского API и ориентацию на Temporal Cloud.

Антон Титов недавно запостил статью Leveraging Temporal for Efficient Document Life Cycle Management (перевод от ButschsterGPT можно почитать на хабре). Видя, что Акелла промахнулся, напоминаю вам и Антону, что у нас есть свой блог R&D, где мы иногда публикуем полезные технические статьи.

Надо было брать Bitrix

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


Дурка

Чувак преисполнился любовью и распечатал 1472 страницы документации Laravel. Сделал это он для того, чтобы прочитать её онлайн на камеру. В общем вот видео на 9 часов. Я хз, как это комментировать 🙂

Давайте лучше слушать звук камина и потягивания вискаря

Палата на палату

Говорят, что недавно в нашей больнице поссорились две палаты: палата Rails против палаты React.

Кто победил — не понятно, каждый тянет одеяло на себя. Моя версия событий:

В это время JS
  • Неравнодушная армия Laravel в количестве полусотни твиттер-бойцов пошла гадить в твиттеры разработчиков JS фреймворков. Полагаю, там они утверждают, что Laravel уже захватил фронтенд, и все эти JS фреймворки уже не нужны. Ryan Florence принимает вызов и долго ищет хоть какой-нибудь сайт на Laravel + Livewire. Даже у комьюнити запрашивает (ну серьёзно, кто вообще его использует Livewire?).
  • Разогрев аудиторию, Taylor и Ryan записывают подкаст. Краткий пересказ от YandexGPT тут.
  • Что-то там в твиттерах происходит и Taylor говорит, что 50 долбоёбов нельзя обобщать на всё сообщество Laravel.
  • Ryan Florence говорит, что может сломать любой сайт с Livewire. Ему скидывают какой-то сайт и он ломает его. Не бэк, конечно, а только морду. Буквально, пошёл и хлебало сломал :)
  • Why Don't We Have A Laravel For JavaScript? Видео о том, почему отсутствие монополиста в JS это плюс, а не минус.

В общем это ребячество продолжается до сих пор. Твиттер0-активные больные по прежнему подкидывают дерьмо на вентилятор, но уже не с лопаты. Ждём следующее обострение осенью.


PHP 29 лет 🎂

На этом празднике круче всех оттянулся Роман Пронский: запустил PHP 1.0 и весело провел время на стриме с Brent, Nicolas Grekas, Freek (Spatie) и конечно же слонами. На стриме обсудили разные фичи последних версий PHP и чего они хотели бы видеть в будущих.

Хуже всех, на мой взгляд, годовщину встретили JetBrains. Не то чтобы я их хейтил за "we need to pivot" в отношении Space...

Но если подумать: вот они выкатывают скидку 29% на PHPStorm — круто, вроде бы. А в условиях "только для новых пользователей и для годовой подписки". Это как прийти на приватную вечеринку и сказать, что угощаешь всех за свой счёт, кто не в списке приглашённых.

Отмечу недавний стримкаст про типы, типизирование и ООП. Послушал с удовольствием. Добавлю, что по тегу #Типизация на нашем уканале можно найти релевантные статьи, прекрасно дополняющие тему:

Фреймворки

Некоторые думают, что в PHP всего несколько живых фреймворков, возможно даже три или два. Вот в JS каждый день рождается минимум один, при том время жизни стабильной версии меньше года.

Эти "некоторые" ошибаются. В пыхе не только большое количество живых и даже устоявшихся фреймворков, но также новые появляются как говно после снега. А если вы ещё не начали писать свой фреймворк, вот вам инструкция: "как супер мега просто сделать свой MVC фреймворк". Процитирую самое важное из этой статьи:

Создание PHP-фреймворка с нуля является масштабным мероприятием, и автор не рекомендует делать это самостоятельно.

А тут есть целый курс, как запилить свой фреймворк. Так что велосипедостроение будет процветать и дальше.

К 29 летию PHP можно составить свой топ noname фреймворков.

Resonance

Resonance — самый свежий из недавно всплывших фреймворков. Работает на базе Swoole и DS, а значит создан с целью эффективного решения проблем параллелизма. Автор утверждает, что эти проблемы до него не решал ни один фреймворк. Кейс для резонанса: отправить десятки тысяч долгих параллельных запросов к LLM не сжирая тонну ресурсов. По его замерам выходит в 25 быстрее Laravel Octane.

За почти год разработки фреймворк подходит к версии 1.0.0, поэтому автор призывает приходить и тестировать.

Tempest

Поговорили про Temporal, поговорили про Pest. А что такое Tempest? Их внезапный ребёнок?

Мимо! Tempest — ещё один PHP фреймворк.

Отличается от других фреймворков только тем, что в нём нет конфигов. А значит там нет работы с БД, кешем и всего, что не может жить без конфигурации. Ещё, по задумке, он вообще не должен отсвечивать и мешать разработчику, а значит мне точно не подходит. Но в сообществе может и хайпануть, т.к. его автор, Brent, сам по себе хайповый чувак.

Flow PHP

Это не Full stack MVC PSR (какие мы там ещё 3 буквы знаем) фреймворк для запросов и ответов, а тулза, специализирующаяся на обработке больших наборов типизированных данных при минимальных затратах памяти. Подойдёт если надо переместить данные из одного места в другое, выполняя на лету какие-то действия.

Релиза 1.0.0 пока нет, но список адаптеров уже выглядит внушительно.

Пакет активно развивается и, пожалуй, я его как-нибудь даже попробую.

Кстати, что жирненький csv файлик можно прочитать штатными средствами как-то вот так:

Tersworks

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

Flight

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

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

TUI

TUI PHP (terminal user interfaces) — адаптация Ratatui (Rust) под PHP. Появление таких фреймворков я категорически приветствую. Поддержки винды нет.

В этой статье можно почитать историю создания фреймворка. Жаль, что в репозитории уже пол года нет активности. Видимо разработчик таки нашёл новую работу.

If you want me to stop give me a job! preferably one which involves TUIs but I’m open to anything.

А вот эта консольная приблуда тоже даёт возможность интерактива в терминале (не без помощи FFI), но уже под винду: https://github.com/ZmotriN/php-wcli

FrameworkX

FrameworkX запилен одним из авторов ReactPHP угадайте на чём? Правильно, на ReactPHP. С лозунгом "async made easy" фреймворк так и не дошёл до релиза 1.0.0. Фанатам классики фреймворк может показаться нишевым и не user friendly, но наверное оно так и есть. Если взять во внимание, с каким скрипом аннотация @yield добавляется в React Promises, фреймворк устареет раньше, чем релизнется.

Интересен выбор названия. С одной стороны добавлять X уже старомодно. Даже пользователи твиттера признают что X - стрёмное название. Но с другой стороны забавно, что вспоминается именно этот фреймворк, когда под "Framework X" подразумевается случайный.

Статья маркетинговая, можно не читать

Leaf

Leaf выглядит интересным, юзабельным фреймворком. Хороший ненавязчивый маркетинг, прицел на DX. DX которого часто не хватает — это, конечно же хорошо, но кроме этого ему похвастаться нечем.

Phasync

Phasync — фреймворк асинхронщины. Появился совсем недавно и сейчас активно продвигается автором. Пока он не такой большой, чтобы называться прям фреймворком, на каркасе которого будет держаться приложение. Это скорее набор утилит и асинхронного обвяза на нативном PHP, который легко встроится в любое приложение и не будет вписывать в свои рамки.

С pasync можно постепенно добавлять асинка приложению, параллеля и отправляя разные IO операции в фон. Выглядит интересно и юзабельнее, чем тот же ReactPHP.

Из интересного от автора phasync:

  • Статья-туториал: Writing an asynchronous web server from scratch in PHP
  • Патч в PHP-SRC, который позволяет обрабатывать неограниченное кол-во дескрипторов в stream_select(). Сейчас пыха может только в 1024. Это круто, что чел пошёл патчить кор, чтобы улучшить свою библиотеку.
  • В репозитории проекта есть файл CHATBOT.txt, которым можно наполнить контекст AI ассистента и получать от него внятные ответы об использовании библиотеки.
    Идея интересная и было бы неплохо иметь подобный стандарт. Что-то вроде robots.txt на веб-ресурсах, куда заглянет бот и преисполнится контекстом.

Apex

Апекс (именно так он и произносится, а не орех на букву А) — гибридный фреймворк, созданный чтобы заполнить пробел между CMS и фреймворками. Последний призыв к автора к сообществу можно почитать здесь. Я не очень понял, какие конкретно проблемы он решает, но похоже, что все.

Чел попытался охватить слишком много и не сдюжил. Сложно полагаться на фреймворк, если за ним стоит один человек, ведь Lottery factor (более мягкая версия Bus Factor) никто не отменял. Походу эта штука так и загнулась.

У Apex, кстати, ещё есть лёгкий фреймворк Levis, который тоже уже пол года без коммитов.


Наверное было бы неплохо иметь общие интерфейсы аля PSR, но для сервисов. Там: платёжный шлюз, кошельки, идентификация и прочая дичь с набором DTOшек, имплементации которых могут быть в виде пакетов или API бриджей. Фреймворки пилили бы свои модули, а вендоры — готовые к внедрению имплементации.

Laravel Extended

Зачем писать свой фреймворк с блэкджеком и шлюхами, если можно взять имеющийся и добавить в него хотя бы шлюх? В статье Laravel Under The Hood - Extending the framework рассказывается, как можно навесить какой-то функционал на кусок фреймворка, используя паттерн декоратор.


Кстати о Laravel

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

Например, кейс с роутером. Есть метод контроллера, который связан с маршрутом:

// Controller.php
public function show(PhoneNumber $number) {
    // PhoneNumber — класс сущности.
}

// routes.php
Route::name("show")->get("phone-numbers/{phoneNumber}");

Вопрос: что будет в переменной $number, когда маршрут выстрелит?


В данном случае всегда будет пустая сущность PhoneNumber (зачем?). Но если изменить маршрут на phone-numbers/{number}, то магия потечёт по другому руслу и в метод подгрузится сущность по идентификатору из маршрута. Для разработчика не из хогвардса выглядит всрато и, возможно, какая-то инспекция IDE была тут бы уместна (Adel уже спешит заляпать дыру плагином Laravel IDEA).

Я как бы не против разных удобств типа подгрузки сущности по параметру маршрута или чтобы сущность создавалась сама через сконфиженную фабрику. Но это должно быть контролируемо, без неявных поведений. Нужно заинжектить сущность? Сделай через атрибут:
public function show(
    #[CreateNew] PhoneNumber $number,
    #[FindByRouteParam('number')] PhoneNumber $phoneNumber,
) {...}


В общем, чел придумал, как пофиксить, и с комментарием "We'll see what happens!" пошёл делать ПР в Laravel.

Я напомню, что если вы не входите в команду мейнтейнеров Laravel, то, наиболее вероятно, все ваши потуги закончатся закрытием PR вот с таким сообщением:

Как политкорректно послать нахуй

Просто походите по страницам и посмотрите на соотношение закрытых и слитых PRов. Естественно там можно найти какое-нибудь говно, но те PR, что я открывал, были таки годными.

Поскольку Steve Bauman не последний пацан на районе и имеет 5к+ подписчиков, его PR не закрыли сразу, а отправили в черновик, чтобы вернуться к нему когда курнут. Ставлю на то, что потом закроют.

Однако не теряйте надежду! Если вы хотите что-то законтрибутиь в Laravel, то специально для вас запустили курс "как контрибутить в ларку" на Laracast.

Курс бесплатный, возможно даже годный, но всё-равно не даёт никаких гарантий, что вы сможете пропихнуть свой Pull Request.

Поэтому нахер ларку. Хотите поопенсорсить — приходите улучшать Spiral, допиливать Yii и двигать Buggregator.

Кстати, у нас до сих пор проходит мероприятие вокруг контрибутинга в Buggregator с призами, нужно просто регулярно что-то делать.


Active Data Mapper 😱

Ещё на тему "внезапных детей". Какой был бы ребёнок у ActiveRecord + DataMapper?

Вот первый вариант, когда атрибуты Cycle или Doctrine вешаются на модели Eloquent:

Пока информации мало, но выглядит уже лучше, чем было до этого. И будет ещё лучше с автогенерацией миграций и мапперами.

ЯННП, но, наверное, иллюстрация к месту


Второй вариант: cycle/active-record. Из названия понятно, что это Active Record на базе Cycle, который, вроде, Data Mapper. В чём подвох?

А подвоха нет. Мы уже как-то говорили, что Cycle ORM — это конструктор. Здесь есть всё необходимое, чтобы сделать ORM своей мечты. Даже классы для сущностей не обязательны и схему можно менять на лету.

Новый пакет полностью совместим с классикой Cycle. Можно любую сущность накачать функциями любимого паттерна, просто унаследовав от класса ActiveRecord. Всё кастомизируемо, есть ActiveQuery и даже что-то новое: ActiveRepository. Совмещает в себе плюсы репозитория и ActiveQuery:

  • по умолчанию иммутабельный
  • можно привязать к сущности, а можно не привязывать
  • нет ограничения "у сущности может быть только один репозиторий"
  • не является сущностью QueryBuilder, а значит может следовать контракту с ограниченным набором методов.

Cycle AR в предрелизном состоянии и наполняется документацией. Если вы заинтересованы в его развитии – приходите с идеями в репозиторий или TG чат.

OpenSource

Мы уже выяснили, что Laravel — не то место, куда стоит идти и делать мир лучше.

А куда?

  • Недавно завершился конкурс контрибьюторов MoonShine. Надеюсь, участники получили удовольствие от процесса. Александру @Pir_a_zhok наши поздравления.
  • В Buggregator в начале мая тоже стартовал конкурс, но мы его продлеваем, пока не наберутся победители. К нам приходили отличные ребята, приносили отличный код, но потом разом куда-то делись. Вернитесь!!!
  • Cycle ORM. Кстати, Cycle Active Record на 90% написан энтузиастом @lotyp. Человек просто пришёл и предложил свою помощь по Cycle: улучшил презентабельность и CI некоторых репозиториев, взялся запилить AR и даже в конкурсе контрибутинга в Buggregator поучаствовал.
  • Фреймворку Yii постоянно нужна свежая кровь. Нет, мы не вампиры и бояться нас не надо. Просто приходите не только с вопросом "когда релиз", но и с предложением помощи, чтобы этот релиз приблизить.
  • А вот фреймворку Spiral нужно просто немного человеческого внимания. Фреймворк не хуже и не сложнее "большой тройки", и наоборот более сложные решения на нём пилить даже проще. Просто нужен фидбек, чтобы заполировать какие-то неровности.
  • Опенсорсить можно не только в сторонний продукт. Можно делать что-то своё, чего не хватает в этом мире. Например:
    - Сергей vjik Предводителев попиляет свой тайпкастер для Cycle (приблуда для приведения типов между БД и PHP). Очень удобная штука и может быть удачным дополнением к любимой ORM.
    - Валентин vudaltsov Удальцов помимо походов в PHP SRC уже давно и тщательно разрабатывает Тайфун, пропитанный слюнями тех, кто его ждёт.
    - Дмитрий xepoz Дерепко запилил мокер internal функций с целью тестирования.
    - Кирилл SerafimArts Несмеянов тоже постоянно пилит какую-то не всегда понятную херню. Вот сейчас это Boson (хотел добавить во фреймворки, но пока хз что писать, т.к. у меня не запускается).
    - Павел butschster Бучнев тоже начинал Buggregator пилить несколько лет назад как локальный проект. Да и назывался он в начале по-другому.
    И таких примеров много.

Приходите, помогайте. Ведь опенсорсу вы нужны не меньше, чем он вам.


Следующая часть ➡️

Report Page