Пых
8.26K subscribers
263 photos
16 videos
6 files
579 links
Блог Валентина Удальцова о разработке на PHP.

Хобот @phpyhobot
https://youtube.com/@phpyh
https://vkvideo.ru/@phpyh
https://t.me/isPHPdying

Статистика: https://t.me/INOTAROBOT?start=st1219340804

Для связи используйте личные сообщения канала.
Download Telegram
Завтра будет PHP-трек!

А сегодня послушал очень вдохновляющий доклад Семихатова про то, как математика в теории много раз предвосхищала открытия на практике.
🔥5115👍13🦄3
У Thesis наконец-то появился логотип!
🔥56👍26🎉10😁52
🗄️ Спаси свой репозиторий от save()

Возвращаюсь к своим образовательным идеям — сегодня закинул в Хобота платную лекцию про репозиторий. Периодически вижу неправильный нейминг и холивары про то, где вызывать flush().

В этой лекции мы разберёмся, что такое репозиторий, почему в нём не должно быть методов save() и update() и где же на самом деле нужно вызывать $entityManager->flush().

А ещё:
• поговорим про паттерны реализации логики и паттерны доступа к данным по Фаулеру,
• сравним Active Record и Data Mapper,
• обсудим, почему метод find() удобнее get(),
• соберём руками Doctrine безо всяких фреймворков,
• увидим, где суффикс Interface мешает делать красиво,
• поручим одну и ту же задачу Junie и Claude и узнаем, кто лучше.

Залетай в Хобота и смотри.
🔥41👍237👎6🗿2
This media is not supported in your browser
VIEW IN TELEGRAM
The State of PHP 2025 — изучаем результаты опроса JetBrains

Несколько цифр:
• РФ на 3 месте по кол-ву участников опроса,
• 58% опрошенных не собираются уходить с PHP,
• 89% респондентов на PHP 8.x,
• 42% всё ещё не используют инструменты качества кода,
• 32% не пишут тесты.

YouTube | VK Видео
👍38🔥127
Оценка зрелости инженерных процессов

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

Ребята уже нашли несколько интересных корреляций:
• между скоростью пайплайнов и качеством code review,
• между алертингом и стабильностью релизов,
• между ролями в команде и удовлетворённостью релизным процессом.

Каждая новая анкета повышает качество данных, отделяя закономерности от шума.

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

https://forms.gle/NszR7VDuXL9sBbVAA
👍94
Пых
Thesis Amqp 1.0.0 Многие заметили, что в проекте Thesis уже несколько месяцев подряд происходит какая-то движуха. Если вкратце, мы с Вадимом решили под этим именем выпустить набор современных асинхронных компонентов для PHP, а в будущем, вероятно, и свой…
🤎 Драйвер для NATS от Thesis!

Каждый, кто пишет на Golang, наверняка слышал про NATS. Это платформа для обмена сообщениями, состоящая из двух основных частей: Core NATS (publish-subscribe с at-most-once гарантией и request-reply) и JetStream (персистентные стримы а-ля Kafka).

Мы написали новый неблокирующий драйвер для NATS под PHP, который поддерживает все основные возможности платформы:

• publish-subscribe,
• request-reply,
• jetstream,
• key-value хранилище,
• объектное хранилище,
• атомарные счётчики на основе CRDT,
• пакетная публикация,
• планировка сообщений.


composer require thesis/nats



$nats = new Nats\Client(Nats\Config::default());

$nats->subscribe('foo.*', static function (Nats\Delivery $delivery): void {
dump("Received message: {$delivery->message->payload}");
});

$nats->publish('foo.bar', new Nats\Message('Hello World!'));


Текущий релиз — 0.2.0, но некоторые уже используют драйвер в продакшне! К мажору шлифанём по мелочи и добавим поддержку NATS Service. А ещё после статьи на Reddit нам поставил звезду Ocramius. 😅

GitHub | Thesis Community | nats.io
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥65👍2211👏2
Пых
Кто хочет в эти дни купить слоника Пых в Санкт-Петербурге — заполните форму, чтобы я понимал, сколько взять с собой. https://forms.gle/TmVwGNSwmwktJ5Bd8
💙 Слоник Пых на Ozon

Теперь коллекционного слоника Пых, произведённого в рамках краудфандинговой кампании, может купить каждый!

https://www.ozon.ru/product/plyushevyy-slonik-pyh-2985086261/
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥39🥴28👍12🖕64🤮3
Пых
💙 Слоник Пых на Ozon Теперь коллекционного слоника Пых, произведённого в рамках краудфандинговой кампании, может купить каждый! https://www.ozon.ru/product/plyushevyy-slonik-pyh-2985086261/
Окей, ребята, я вас услышал: цена получилась слишком высокой. Для понимания: это не я решил разбогатеть — это комиссия Озона такая большая (больше трети с каждой продажи).

И сейчас до меня дошло, что те услуги, за которые Озон берёт такой процент, мне вобщем-то не нужны — я могу продавать вам из рук в руки.

Дайте мне несколько дней, я попробую автоматизировать продажи слоников с доставкой через Хобота. Кто заказал — можете отменить.
36👍26🔥13🤮4
Наполнение списка при деструктуризации

Иногда из функции надо вернуть кортеж (иммутабельную группу значений), а в DTO смысла нет, потому что это разовая ситуация и непубличное апи.

В этом случае я всегда использую запечатанный list shape, потому что его очень удобно разбирать в переменные при помощи синтаксиса деструктуризации массива: [$a, $b] = $tuple.

Сейчас мне потребовалось в цикле раскидать возвращаемые методом значения по двум спискам. Приятно удивился, что при деструктуризации можно использовать не только [$array['key']] = , но и [$array[]] =.

Упрощённый пример:


interface Thing
{
/**
* @return list{int, string}
*/
public function resolve(): array;
}

/**
* @param iterable<Thing> $things
*/
function app(iterable $things): void
{
$ints = [];
$strings = [];

foreach ($things as $thing) {
[$ints[], $strings[]] = $thing->resolve();
}

var_dump($ints, $strings);
}


PHPStan | Psalm
🔥65👍37😱16👎5👀42
Нюансы вариадических функций

Копаясь в статанализе в рамках проекта Typhoon, мы про каждую мелочь стараемся думать во всей полноте, чтобы не упустить даже очень редко используемые возможности PHP. Так мы периодически узнаём что-то новое.

Например, есть тип callable(<params>): <return type>. У параметров есть следующие модификаторы: = (со значением по умолчанию), ... (вариадический), & (передаётся по ссылке). Вопрос: как их можно сочетать?

1. Параметры, передаваемые по ссылке, очевидно, могут иметь значение по умолчанию.
2. Вариадические, очевидно, не могут иметь значения по умолчанию.
3. Могут ли вариадики передаваться по ссылке? Вот тут лично для меня уже неочевидно, потому что я вообще редко что-то передаю по ссылке.

Разбираемся. Вариадические функции добавил Никита Попов в далёком 2013 году (до этого все использовали func_get_args()), и вот что написано в RFC:

By-reference capture

The new syntax additionally adds support for capturing variadic arguments by-reference, something that was previously not possible in userland code. Only internal functions could make use of this via ZEND_ACC_PASS_REST_BY_REF.

This would allow implementing functions like sscanf() or mysqli_stmt::bind_param() in userland.

A by-reference capture of variadic arguments is indicated by a & before the ellipsis ....


Пробуем:


function increment(int &...$ints): void
{
foreach ($ints as &$int) {
++$int;
}
}

$a = 0;
$b = 100;

increment($a, $b);

var_dump($a, $b); // 1, 101


Получается, в параметрах типа callable возможны только два сочетания: &... и &=.

Кстати, обратите внимание: слово "опциональный" не является точным определением для = параметра. Опциональные параметры — это те, которые можно не передавать, к ним относятся не только параметры со значением по умолчанию, но и вариадические. Поэтому = однозначно определяется именно как параметр со значением по умолчанию (у нас в коде bool $hasDefault, а не $isOptional). Этот нюанс хорошо прослеживается в нативной рефлексии:


$reflection = new ReflectionParameter('increment', 'ints');

var_dump(
$reflection->isOptional(), // true
$reflection->isDefaultValueAvailable(), // false
);
👍31🔥13😨105
Typhoon учится выводить дженерики

Всю неделю контрибьютил в алгебру типов Typhoon (пока в приватном репо), в частности научился программно решать системы линейных уравнений над типами.

На скриншоте вы видите, как алгебра выводит результат вызова полиморфной функции а-ля array_combine. Причём делает это с анонимной сигнатурой буквально "на весу".

Аналогичный код в PHPStan (выводит верно, но с нерелевантными ошибками) и Scala.

Дальше больше...

Примечание: PHPDoc просто для понимания описываемой сигнатуры, он никак не парсится алгеброй.
🔥30👍15🥴84❤‍🔥2🤯2😱21
Два простых правила

Вот сколько лет я ни пишу код, без конца убеждаюсь в двух вещах:

1. Если стоит выбор между мутабельностью и иммутабельностью — без раздумий выбирай иммутабельность.
2. Если стоит выбор между наследованием и композицией — без раздумий выбирай композицию.

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

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

Интересно, что и мутабельность, и наследование осложняют типизацию и привносят костыли: @self-out, @this-out, @require-extends.

Я не Егор Бугаенко и не утверждаю, что мутабельность и наследование прям вот совсем не нужны. Но если есть выбор (90% случаев на моей open source практике) — советую воздерживаться.
💯92👍42🔥11🤔74🫡3
9 полезных плагинов

В блоге JetBrains вышел обзор плагинов Димы Дерепко:

.​gitattributes support
Git Codeowners
Cron / Crontab Support
Sitemap Support
TempestPHP (поддержка фреймворка автора канала PHP Annotated)
🪲 Buggregator
PHP Dump (показывает опкоды и AST)
FileSystem Info (выводит информацию по папкам и файлам: кол-во файлов, размер, LOC)
Git Churn (анализирует частоту изменений файлов в Git)

https://blog.jetbrains.com/phpstorm/2025/11/phpstorm-plugins-you-might-not-know/

P.S. Мне Дима тоже периодически предлагает сделать что-то полезное для моих проектов. И у меня уже есть идея!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41🔥189😴5
Ищу напарника на стрим по Typhoon

На следующей неделе хочу провести Typhoon-стрим. Мы наконец-то напишем простой инструмент на базе typhoon/type, который будет полезен в самых обыкновенных проектах.

Чтобы было веселее писать код, приглашаю любого из вас присоединиться в роли второго пилота. Нужно быть в теме статического анализа в PHP, оценивать свой уровень на middle+ и не бояться говорить на камеру в прямом эфире.

Желающие, скидывайте в личные сообщения канала Пых свой GitHub.
👍14🔥135😁1
Убираем null?

В конце месяца совместно с Garage Eight и Live PHP делаем митап в Санкт-Петербурге. Регистрация откроется через неделю.

В числе спикеров отчаянный борец против nullВладимир Романичев.

Вчера мы прогоняли его доклад, а сегодня я кидаю вам пример рефакторинга своего кода...

Было

final class Context
{
/**
* @var array<non-empty-lowercase-string, Name>
*/
private array $uses = [];

public function __construct(
public readonly ?Name $namespace = null,
) {}

public function use(Name $name, ?Name $as = null): self
{
$context = clone $this;
$context->uses[($as ?? $name->last())->toLowercaseString()] = $name;

return $context;
}
}


Стало

final class Context
{
// ...

public function use(Name $name): self
{
return $this->useAs($name, $name->last());
}

public function useAs(Name $name, Name $as): self
{
$context = clone $this;
$context->uses[$as->toLowercaseString()] = $name;

return $context;
}
}


Я не считаю null абсолютным злом, тем более, что в PHP он явный, но иногда действительно можно сделать красивее без него.
👍37🥴3413🔥12👎5🤔5🤡4
Garage Eight × LivePHP × Пыхап в Санкт-Петербурге

В следующий четверг в 18:30 мы совместно с Garage Eight и Live PHP делаем митап в офисе "гаражей".

В программе:
💣 NULL. Выбросить нельзя использовать
После этого доклада от Владимира Романичева разрешается бить морды.

🧬 RabbitMQ: как кворумные очереди окончательно победили зеркалированные
Виктор Михайлов расскажет, как использовать надёжные реплицируемые очереди в кролике.

🧠 Архитектура ИИ-сервиса для распознавания документов
Михаил Мироненко покажет путь от MVP до продакшена.

✌️ Офлайн-гостей ждут угощения и экскурсия по офису Garage Eight с панорамным видом на город. Плойка и кикер также к вашим услугам!

📍 Митап пройдёт 27 ноября в 18:30 в питерском офисе Garage Eight. Вход бесплатный, но нужно зарегистрироваться.

📹 Как обычно, будет трансляция на YouTube и VK Видео с записью!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍27🔥188
Только что на php.net опубликовали PHP 8.5!

Тег уже два дня как стоит, но я ждал финального аккорда.

По этому поводу держите мой доклад со Стачки «PHP 8.5 не сбавляет темп!». Из него вы узнаете про основные фичи новой версии и нюансы их применения.

Основные таймкоды:
01:04 Все способы получения первого элемента массива в PHP (в т. ч. бредовые)
05:20 Pipe operator v3
10:56 URL Api
17:20 Clone with v2
21:24 #[NoDiscard]
24:07 Closure и FCC в константных выражениях
27:57 Persistent cURL handles
29:33 Асимметричная видимость статических свойств
30:00 Рекурсивные замыкания
37:41 Типизируем array_first()

https://youtu.be/OIFbU5oypig
https://vkvideo.ru/video-228746873_456239122
http://vudaltsov.github.io/php8.5-slides
https://php.net/releases/8.5/ru.php
5🔥70👍253