PHP Fart Time
1.73K subscribers
80 photos
4 videos
2 files
170 links
Привет, фартаны!

Дурачимся, пилим OpenSource и рассказываем про пердовые технологии в php.

Авторы контента: @roxblnfk и @butschster
Download Telegram
Крошка Джун к Мидлу пришёл, и сказала кроха — что такое "хорошо", а что такое "плохо"?

Предлагаю нагенерить идеи Хорошо/Плохо для повышения квалификации PHP-комьюнити
Уважаймые подписчики! Вы верно чли первое правило клуба - не рассказывать о клубе. Но теперь ничего не поменялось и мы встали перед выбором. Готов ли наш канал выйти в массы?
Anonymous Poll
72%
Контент - говно, но вы держитесь. Запускай!
28%
Контент - говно, но PHP-комьюнити не заслуживает даже этого. Остаёмся закрытым элитным клубом.
В последнее время люди из моего окружения начали активно пользоваться Obsidian для ведения заметок и агрегирования информации. После восторженных отзывов уже и я не мог пройти мимо. Не может же быть всё так замечательно.

Оказывается, может!
Отличный markdown-редактор, теги, ссылки как в wiki, удобный и быстрый интерфейс с тёмной темой, даже плагины есть. Markdown рендерится красиво - блоки кода подсвечиваются, mermaid поддерживается, горячие клавиши работают, всё максимально юзабельно.

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

Собираю всё своё разбросанное по разным хранилищам в одно место, сохраняю интересные статьи со ссылками на источник и нужными тегами.

Пока сеть заметок маленькая. Посмотрим, что будет через месяц-другой.

Обсудить Obsidian-flow го в комменты.
#Article #Типизация #php

#️⃣ Variadic параметр

Вроде тут и сказать нечего. Ну поставил три точки в параметре и всё.
Ан нет. Приколов хватает. Погнали 

⭕️ Что известно

Variadic параметр, он же "списки аргументов переменной длины", пользователем с помощью добавления (сюрприз!) многоточия. Примерно столько вы можете прочитать про variadic в документации. А ещё про то, что в него можно распаковывать итерируемые значения другим многоточием.

function toArray(...$items): array { return $items; }
$a = ['foo', 'bar'];
toArray(...$a);


Variadic является опциональным параметром. Всегда. Т.е. вы можете ничего в него не передавать и ему с того норм.

> Кстати, многие путают понятия "аргумент" и "параметр". Параметр - то, что в определении функции, аргумент - значение, которое передаётся в функцию.

Зачем он нужен, если и так можно передать сколько угодно аргументов, а потом вынуть их с помощью func_get_arg(), как делали ещё наши предки? Кроме того, мы можем в конце списка параметров сунуть массив и даже распаковка не понадобится при вызове функции. function foo(Foo $a, array $myVariadic = []) {}.
А затем, что в variadic умеет в типизацию! (про типы см. предыдущий пост).

function foo(Foo $a, Bar ...$variadic) {}


Теперь только объекты Bar попадут в массив $variadic. Ну это и так все знали.

⭕️ Приколы с распаковкой

Распаковывая iterable в variadic, ключи могут быть разные. Если вы распаковываете список (ключи типа int), то их порядок будет сброшен. Т.е. распаковка массива [3 => 'a', 2 => 'b', 1 => 'c'] приведёт к ['a', 'b', 'c'] в вариадике.
Ассоциативный массив останется ассоциативным массивом с теми же ключами.
Но не всегда можно смешивать целочисленные ключи со строковыми. При распаковке аргументов из массива, как и при передаче именованных+позиционных аргументов, позиционные аргументы должны идти перед именованными. Причём сортируется это по параметрам 💥

⭕️ Именованные аргументы (PHP 8.0)

Поиграем в игру. Есть сигнатура bar(int $a = 1, int $b = 2, int ...$c). Что попадёт в $c?

(если нажать на один скрытый элемент — откроются все)
bar(a: 1, c: 3) - `["c" => 3]`
bar(c: [1, 2, 3]) - `Fatal Error`
bar(foo: 3) - `["foo" => 3]`
bar(1, 2, a: 3) - `Fatal Error`
bar(c: 3, a: 1, b: 2) - `["c" => 3]`
bar(foo-bar: 3) - `Syntax Error`
bar(1, 2, 3, 4, foo: 5) - `[3, 4, "foo" => 5]`
bar(b: 2, 3, 4, foo: 5) - `Fatal Error`
Сколько промахов?
Как итог: распаковка аргументов из массива даёт возможность передать любой сроковой ключ, именованные аргументы — нет.

⭕️ Хрень какая-то. Где оно надо то вообще?

- Когда нужна типизация на списке аргументов, при этом не нужно сохранять ключи. При этом сигнатура точно не будет дополняться. Например, в yiisoft/injector в конструктор можно было бы передавать переменное число ContainerInterface, а не один и только один (@samdark, я смотрю на тебя). Или вот пример, как заставить передать минимум один аргумент нужного типа: function setEncoders(Encoder $encoder, Encoder ...$encoders) {}.

- В атрибутах, которые конфижат непонятно что. В атрибуте Column компонента cycle/orm можно передать любые именованные аргументы сверх тех, что предопределены заранее (спасибо, variadic). Например, определяем #[Column(type: 'bigint', unsigned: true). Здесь unsigned попадёт в variadic и, если у вас MySQL, столбец будет unsigned.

⭕️ Аннотации

Артефакты прошлого ещё долго будут встречаться в коде даже современном. Да, это про аннотации. Там variadic'и не поддерживаются. До недавнего времени они вообще фейлили парсер doctrine/annotations, однако там решили ограничиться просто фиксом "чтоб не падало". Поэтому (и не только) не пользуйтесь аннотациями, если есть возможность пользоваться атрибутами.

⭕️ Поддержка IDE

Её нет. Пока нет известного мне способа рассказать IDE или Psalm'у, какие ключи можно передать в variadic. Можно описать тип только одного (каждого) передаваемого элемента. Если вам известно об этом больше - го в комменты.
#Article

Привет, привет всем любителям PHP! 🎉 Хочу поделиться свежей статьей под названием "Как раскрыть сверхспособности высокопроизводительных очередей для PHP-приложений и не сойти с ума!" 🚀

Знаете, я изучал тему очередей на PHP и обнаружил пару проблемок. Вроде бы все классно, но, честно говоря, PHP не слишком подходит для крутых инфраструктурных штуковин. Такой интерпретируемый характер и блокирующая модель IO могут сильно торомозить их работу Короче это тупо неэффективно. 🤔

И вот однажды один человек подумал, а почему бы не использовать в этом деле Golang? 🔥 Go умеет делать кучу дел одновременно (горутины), управляет ресурсами как настоящий профи, работает быстро как молния и еще и сокетами управляет на уровне близком к железу. Просто магия!

Итак, в моей статье я рассказываю о супер-мега-крутых очередях на RoadRunner (о плагине "Jobs"). 💪 Там PHP и Go нашли свою любовь и объединились в команду. Теперь PHP-разработчики могут наслаждаться всеми плюшками обоих языков и создавать высокопроизводительниые шедевры!

Но это еще не все, фартаны! Также, я раскрываю стратегии использования очередей. Мы будем погружаться в мир загадочных штуковин, как "Фанатик с запоздалыми задачами", "Король бесконечных повторений" и "Независимый ковбой с ретрайами". Это как сказка, только в мире программирования!

Так что, прямо сейчас отправляйтесь по ссылочке https://butschster.medium.com/unleashing-the-power-of-high-performance-queue-services-for-php-applications-dcc5c1426511! 😄

#PHP + #Go = Unstoppable! 💪

Жду ваших комментариев и обсуждений! 🙌

P.s. Мы как-то побенчили джобы разных реализаций. Оказалось, что очереди в отделении почты разгребаются быстрее, чем в Laravel.
#МыслиВслух
Мы с Павлом как-то готовили доклад. Начали делать его примерно за 2 часа до выступления. Наверное поэтому получилось так всрато, но сносно. Там я говорил о том, что экосистема Spiral акцентируется на объединении разных миров разработки, а скорость - просто приятный бонус: gRPC имплементируется на любом популярном языке, у Temporal есть SDK на разных языках, кроме того, RoadRunner хорошо объединяет go и PHP.

Так вот.
Сегодня я обратил внимание на такую вещь, что объединение миров работает и в другую сторону — не на расширение стека, а на сужение.

Вы когда-нибудь решали задачу утилизации компетенций?
Нафига нам питонист, если задачу можно сделать в одном PHP стеке? Но питонист уже есть и мы не можем его заменить. Нужно его эффективно утилизировать. Берём Temporal и пусть питонист питонирует. Его труды идеально встроятся в наши Workflow!
Добавлю только, что без sudo не удалится. Не благодарите.
Этот пост напомнил об одной интересной картинке: https://proxify.io/worlds/php.
Поставил бы там что-то позитивное мужицкое, но можно только сердечко.

А для вас, фартаны, ивент: ставьте здесь сердечко, если вы тоже фанатеете от Laravel и Тейлора.
https://t.me/tg_5minphp/1165

Для меня неожиданно тут только то, что кто-то использует Symfony Container вне Symfony.

Мы с @butschster уже бенчили контейнеры и Yiisoft/di уверенно держится в ТОП 2 — в 2.5 раз быстрее, чем у Laravel по автовайрингу и доставанию из кеша.
PHP-DI в 3.5 раза быстрее контейнера Laravel.

> Стоит посоветовать ему Yii3 DI?

Не стоит. Вот его ответ на эту тему:

> While performance is criteria, so it the community, so they can contribute this package without learning a new framework. So Symfony/Laravel are the only options today.

Томас уже прибухнул с Тейлором и теперь он один из тех чуваков на картинке выше :)

PS: @petrmyazin когда уже сделаешь комментарии к каналу?
#Article

Написал длиннопост, который не влез в формат телеги и телеграфа.
⚠️ Алерт: там много англицизмов.
Читать на гитхабе: Cycle ORM до связей жадный

Надеюсь факт наличия сего писания сведёт к забвению и зарастанию тропы, ведущей к одним и тем же граблям, на которые я наступаю уже далеко не первый раз, но о которых постоянно забываю.
PHP Fart Time
Привет, фартаны! Мы вернулись к истокам и записали видосик. За последние полгода Buggregator Server круто прорефакторился 💪, поэтому напомнить о нём будет не лишним. https://youtu.be/qsDIHwS58Q4
MOSHED-2023-8-8-0-11-49.gif
15.9 MB
А ещё мы релизнули пакет buggregator/trap, который поможет дампать protobuf объекты. Эта утилита умеет ловить любой трафик и даже почту, а ещё у неё есть все шансы стать шлюзом к Buggregator Cloud.
Написано на PHP с любовью и файберами🧵

Залетайте хейтить и рефакторить код! Предлагайте идеи. Например, отличная идея - добавить поддержку MQTT протокола - если тоже пилите умный дом и вам актуально - поставьте эмоджу.
Кстати, почему там ещё нет предложения добавить команду trap fart?

#Buggregator
gRPC и protobuf

В этом стриме мы:
- Призвали мейнтейнера RoadRunner и гуру Golang/Rust Валеру
- Обсудили gRPC и protobuf, особенности работы с ними на PHP.
- Показыли, как сделать сгенерированные из protobuf классы не такими всратыми.
- Обозрели Buf и продемонстрировали его применение.

https://youtu.be/E61resEfgUE
Через полтора часа стрим!
На этот раз прямо в ютубчик и под пиво.

Присоединяйтесь. Поговорим про RoadRunner.

https://www.youtube.com/live/3WdSCnzsFKE?si=aB3TeAGj_19ixsxK
#Article #Типизация #php

Всем нравятся Constructor Property Promotion, не так ли?

final class Foo {
public function __construct(
public bool $bar = false,
public array $baz = [],
) { }
}

☝️ эти фрагменты кода эквивалентны 👇

final class Foo {
public bool $bar;
public array $baz;

public function __construct(
bool $bar = false,
array $baz = [],
) {
$this->bar = $bar;
$this->baz = $baz;
}
}

Но не эквивалентны этому:

final class Foo {
public bool $bar = false;
public array $baz = [];

public function __construct(
bool $bar = false,
array $baz = [],
) {
$this->bar = $bar;
$this->baz = $baz;
}
}

Разница в наличии значений по умолчанию у свойств.

Теперь попробуем создать объекты из обоих вариантов через рефлексию без использования конструктора.
https://3v4l.org/0tLcM

object(Foo)#3 (0) { ["bar"]=> uninitialized(bool) ["baz"]=> uninitialized(array) }
object(Foo)#3 (2) { ["bar"]=> bool(false) ["baz"]=> array(0) { } }

Если у свойства нет значения по умолчанию, то оно будет неинициализированным.

Такой способ создания объектов в обход конструктора широко используется под капотом многих библиотек, не только тех, которые используют doctrine/instantiator.
И иногда это стоит учитывать при работе с классами, которые будут проходить через гидрацию или демаршализацию. У меня такое уже выстреливало 😳.

А если ты счастливый пользователь Cycle ORM, то я рекомендую вообще закрывать конструкторы сущностей (делать пустой приватный конструктор) и вместо этого писать фабрики.
#ВредныеСоветы #Типизация #php

Как сломать типизацию:
https://3v4l.org/nTogS

Как сломать readonly (и типизацию):
https://3v4l.org/gSWFF

Также не забываем про пакет unfinalize.

Что там ещё нам мешает писать код по своим правилам?