Telegram Web Link
Podlodka PHP Crew «Практическая архитектура»

На следующей неделе стартует пятая Podlodka PHP. Программа:

• Упорядочиваем хаос: архитектурная документация по модели C4 / Кирилл Сурогатов
• Как стать x2 разработчиком, используя явное состояние / Кирилл Мокевнин
• Нам уже нужен CQRS? А теперь? / 💙 Валентин Удальцов
• PHP + Prometheus: Работа с кастомными метриками / Алексей Солодкий
• RabbitMQ vs Kafka: обрабатываем большие объёмы / Михаил Каморин
• Построение качественных банковских интеграций на PHP / Дмитрий Кириллов
• PHP будет долго жить: переезжаем на Roadrunner / Владимир Плахотников
• Нет ничего более постоянного, чем Temporal / 🔥 Павел Бучнев, Алексей Гагарин
• Перевозим приложение на PHP в Kubernetes / Вадим Дворовенко

Сегодня последний шанс купить билет по сниженной цене. По промокоду phpyh5 можно получить дополнительную скидку 500 руб.

https://podlodka.io/phpcrew
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍21🔥111🥴1
Контекст в PSR-3 Logger

Периодически сталкиваюсь с неправильным использованием $context в PSR логгере. Давайте вместе внимательно перечитаем стандарт.

1.3.1 Every method accepts an array as context data. This is meant to hold any extraneous information that does not fit well in a string. The array can contain anything. Implementors MUST ensure they treat context data with as much lenience as possible. A given value in the context MUST NOT throw an exception nor raise any php error, warning or notice.


Жирным выделил то, что многие упускают: вы можете передавать в контекст абсолютно любые значения, в том числе массивы, объекты, замыкания и ресурсы. Не нужно самостоятельно проводить нормализацию. По стандарту это задача логгера, а не ваша. Вот как, например, Monolog обработает контекст со сложными элементами:


$logger = new Monolog\Logger(
name: 'app',
handlers: [new Monolog\Handler\StreamHandler(STDOUT)],
processors: [new Monolog\Processor\PsrLogMessageProcessor()]
);

final readonly class Foo
{
public function __construct(
public string $public = 'bar',
private string $private = 'baz',
) {}
}

$logger->debug('Message', [
'birthday' => new DateTimeImmutable('06.04.2019'),
'object' => new Foo(),
'closure' => static fn (): int => 1,
'resource' => STDIN,
]);


[2024-09-27T13:02:16.303651+00:00] app.DEBUG: Message {"birthday":"2019-04-06T00:00:00+00:00","object":{"Foo":{"public":"bar"}},"closure":{"Closure":[]},"resource":"[resource(stream)]"} []


1.3.2 If an Exception object is passed in the context data, it MUST be in the 'exception' key. Logging exceptions is a common pattern and this allows implementors to extract a stack trace from the exception when the log backend supports it. Implementors MUST still verify that the 'exception' key is actually an Exception before using it as such, as it MAY contain anything.


Исключения нужно добавлять в контекст с ключом 'exception'. Никогда не раскладывайте объект исключения на массив вида ['message' => $e->getMessage(), 'line' => $e->getLine(), ...] — так вы не даёте процессорам и форматтерам самим принять решение относительно состава лога исключения и глубины его нормализации.


$logger->critical('Oops!', [
'exception' => new LogicException(
message: 'Level 2',
previous: new RuntimeException('Level 1'),
),
]);


[2024-09-27T13:14:04.880133+00:00] app.CRITICAL: Oops! {"exception":"[object] (LogicException(code: 0): Level 1 at test.php:27)\n[previous exception] [object] (RuntimeException(code: 0): Level 2 at test.php:29)"} []


1.2.2 The message MAY contain placeholders which implementors MAY replace with values from the context array.
Placeholder names MUST correspond to keys in the context array.
Placeholder names MUST be delimited with a single opening brace { and a single closing brace }.
Placeholder names SHOULD be composed only of the characters A-Z, a-z, 0-9, underscore _, and period .. The use of other characters is reserved for future modifications of the placeholders specification.
Users SHOULD NOT pre-escape placeholder values since they can not know in which context the data will be displayed.


Ну и конечно же не забывайте про плейсхолдеры в сообщении. Вместо интерполяции и sprintf куда удобнее писать так:


$logger->notice('Process {pid} started at {time}', [
'pid' => getmypid(),
'time' => new DateTimeImmutable(),
]);


[2024-09-27T13:23:29.306682+00:00] app.NOTICE: Process 45104 started at 2024-09-27T13:23:29.306681+00:00 {"pid":45104,"time":"2024-09-27T13:23:29+00:00"} []
6👍136🔥389
Live PHP meetup 3 октября

В этот четверг в Санкт-Петербурге пройдёт очередной Live PHP. Вот мои ожидания от докладов.

GIGA IDE Cloud - сверхновая IDE во вселенной веб-разработки. Хочу послушать из первых уст про успехи Сбера на поприще IDE. Пора искать замену PhpStorm.
Transaction Script и Transaction Outbox в PHP: Эффективные паттерны для управления транзакциями. В моей картине мира Transaction Script и Transaction Outbox — это как гранатовый сок и гранатовый браслет. Интересно узнать, как Станислав уместил две ортогональные концепции в один доклад.
Страх и ненависть PSR. Недавно с Кириллом Мокевниным (интервью выйдет в октябре) обсуждали, что, несмотря на все проблемы, PHP всё-таки смог в стандарты в отличие от многих других языков. Качественный наброс от Кирилла Несмеянова будет очень кстати. С нетерпением жду!
Как растут проекты. Дима Елисеев, с удовольствием послушаю любые твои мысли, только, пожалуйста, не затягивай. 🙏

Короче, я взял билеты на Сапсан 🚝, и в четверг в 18:30 буду как штык в IT-баре Failover.

https://www.tg-me.com/live_php_news/27
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19👍74🐳2
Через два часа выступаю на Podlodka PHP Crew!

Сегодняшний доклад — результат недавнего переосмысления многочисленных статей и выступлений Udi Dahan про CQRS, наложенный на мой опыт примения и преподавания этого архитектурного стиля.

Мне бы хотелось показать вам CQRS с нестандартного ракурса. Посмотрим, что у меня получится. 🤫

Кстати, я всегда был убеждён, что отец CQRS — только Greg Young, но оказалось, что Udi тоже к этому причастен:

... both myself [Udi Dahan] and Greg Young (arguably the first two to talk about it and the two who ultimately collaborated on naming it – and now Google knows we didn’t mean “cars”) ...
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥33👍11🐳41
В последний момент исправляю рефлексию в PHP 8.4!

На неделе я начал добавлять поддержку PHP 8.4 в Typhoon Reflection, и очень рад, что взялся за это до релиза.

Во-первых, я зарепортил отсутствие обещанной в RFC хуков константы ReflectionProperty::IS_VIRTUAL. Но это тривиально, PR уже готов.

А вот что меня реально загрузило, так это поведение новых методов ReflectionProperty::isPrivateSet() и isProtectedSet() из Asymmetric Visibility RFC. Посудите сами:


final class Foo
{
// isPrivateSet() = true 👌
public private(set) mixed $public_private_set;

// isPrivateSet() = false 🤯
private private(set) mixed $private_private_set;

// isPrivateSet() = false 🤯
private mixed $private;

// isProtectedSet() = true 👌
public readonly mixed $public_readonly;

// isProtectedSet() = false 🤯
protected readonly mixed $protected_readonly;

// isProtectedSet() = false 🤯
protected protected(set) readonly mixed $protected_protected_set_readonly;

// isPrivateSet() = false 👌, isProtectedSet() = false 👌
public bool $virtual_no_set_hook { get => true; }
}


Сначала я подумал, что это баг, и создал тикет php-src#16175. Ilija, автор RFC, объяснил, почему так работает. Дело в том, что у свойств с симметричной видимостью отсутствует флаг ассиметричности. Поэтому для private и private private(set) isPrivateSet() возвращают false, а не true, как было бы логично ожидать. readonly свойства без явного (set) под капотом получают protected (set) (см. "Relationship with readonly" в RFC), поэтому public readonly будет ассиметричным с isProtectedSet() = true, а protected readonly — симметричным с isProtectedSet() = false.

Стало понятно, вот только пользоваться такой рефлексией по-прежнему дико неудобно. В API протекли детали реализации, которые, наоборот, должны быть инкапсулированы. Задача рефлексии — предоставить пользователю комфортный способ изучать код, а не продемонстрировать подкапотное устройство языка.

Но это ещё ладно. Сегодня до меня дошло, что в текущем виде рефлексия в PHP 8.4 ломает обратную совместимость! Если раньше проверка $reflectionProperty->isPublic() гарантировала, что не readonly свойства доступны на запись и чтение из глобального скоупа, то при текущей реализации в 8.4 она будет гарантировать только чтение!


$reflectionProperty = new ReflectionProperty($class, $property);

if ($reflectionProperty->isPublic() && !$reflectionProperty->isReadonly()) {
$object->{$property} = $value;
}


Например, такой код корректно отработает для любых классов в PHP 8.3, но споткнётся на public private(set) $property в 8.4, потому что isPublic() вернёт true, а запись в свойство бросит ошибку.

Вот что я предложил в письме к internals, которое составил в Сапсане по дороге на Live PHP:

ReflectionProperty::isPublic(), isProtected() и isPrivate() должны сохранить своё поведение и возвращать true только если свойство симметричное. Для public readonly метод будет возвращать false, потому что под капотом оно асимметричное с protected(set). Да, это сломает обратную совместимость, но не так критично, потому что все библиотеки уже учитывают тот факт, что в readonly нельзя писать из глобального скоупа.
• Добавить ReflectionProperty::isPublicGet(), isProtectedGet() и isPrivateGet(). Они должны возвращать true, если свойство симметрично или асимметрично доступно на чтение.
• Добавить ReflectionProperty::isPublicSet() и поменять поведение isProtectedSet() и isPrivateSet(): они должны возвращать true, если свойство симметрично или асимметрично доступно на запись.

Вся проблема в том, что недавно вышел PHP 8.4 RC1, и вносить изменения уже поздно. Надеюсь, что мой посыл про нарушение обратной совместимости всё-таки убедит сделать исключение.
5👍45🤯37🔥141
Forwarded from PHP Fart Time (Pavel Buchnev)
Как вы думаете? Почему этот код рабочий?

<?php

https://temporal.io
echo 'Hello, World!';


Вот ссылка, можете проверить
https://3v4l.org/WZBGM
🤔21😁8🔥6🥱1
PHP Fart Time
Как вы думаете? Почему этот код рабочий? <?php https://temporal.io echo 'Hello, World!'; Вот ссылка, можете проверить https://3v4l.org/WZBGM
Ну это, фартаны, известный прикол. А как вы думаете, почему такой код работает?


<?php

echo b'Пых';


https://3v4l.org/D40FF
🤯21😁13
Forwarded from PHP Fart Time (Алексей roxblnfk)
Ну, это-то тоже известная штука, Валентин.

А можешь ли ты уместить решение FizzBuzz в 56 байтов? (ранее рекорд был 52 символа, но недавно обновили версию пыхи, и кое какие хаки перестали работать)

https://code.golf/fizz-buzz#php

У кого короче, тот и выиграл
© wispoz
🎙 Пых-митап 8 ноября!

Друзья, я задумал провести своими силами митап в Москве!

С меня:
▸ кайфовая площадка на 50 человек в центре города (уже забронирована и оплачена),
▸ бесплатный вход,
▸ трансляция и запись,
▸ пицца.

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

https://forms.gle/HKA6AooDDfG8e6PBA

За пару недель до митапа я опубликую полную информацию о мероприятии и ссылку на онлайн-регистрацию. Пока просто пометьте в календаре, что вечер пятницы 8 ноября у вас занят. 😉

До встречи в оффлайне!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍59🔥52🤩711
▶️ Open Source Цех #1. PHP CS Fixer для new без скобок

Не можешь подступиться к задаче? Сделай из неё инфоповод!

Завтра вместо линча законтрибьютим с вами PHP CS Fixer для моего RFC. Я уже немного разобрался с написанием кастомных фиксеров, но на стриме покажу весь процесс от форка до PR, чтобы получилось полное руководство по предложению изменений в Open Source.

https://youtu.be/8sbJq6b9hNI

Всех жду в 18:30!
Please open Telegram to view this post
VIEW IN TELEGRAM
10🔥79👍2051
Пых
▶️ Open Source Цех #1. PHP CS Fixer для new без скобок Не можешь подступиться к задаче? Сделай из неё инфоповод! Завтра вместо линча законтрибьютим с вами PHP CS Fixer для моего RFC. Я уже немного разобрался с написанием кастомных фиксеров, но на стриме…
▶️ Open Source Цех #1. PHP CS Fixer для new без скобок

На этом стриме мы научимся контрибьютить в Open Source, работать с токенами, писать код по TDD и, конечно, опускать скобки в new выражениях!

Я уже в эфире, присоединяйтесь!

https://youtu.be/8sbJq6b9hNI

Получилось офигенно! Спасибо всем огромное. 💙
Please open Telegram to view this post
VIEW IN TELEGRAM
🥰18🔥16👀53👍1
▶️ Какое будущее ждёт PHP? Интервью Кириллу Мокевнину

Недавно пообщались с Кириллом Мокевниным, сооснователем школы Хекслет и автором канала Организованное программирование, про наш с вами любимый PHP. Коснулись множества технических и гуманитарных тем от PSR и RoadRunner до экосистемы и сообщества. Надеюсь, вы так же кайфанёте от просмотра, как мы с Кириллом от записи.

https://youtu.be/1XAbFkMaWxw
https://vk.com/video-224967259_456239053
https://podcast.ru/1734325321
Please open Telegram to view this post
VIEW IN TELEGRAM
👍42🔥205💯1
Следующая версия PHP — 8.5

Если кто-то вдруг, как и я, полагал, что четвёртый минорный релиз будет последним для PHP 8 (по аналогии с PHP 7), то это не так. В ноябре следующего года ожидается PHP 8.5. Насчёт 9.0 нет никакой информации.

Мне это вчера подсветил Рома Пронский. Пруфы в переписках internals и в свежих RFC:
https://externals.io/message/125667
https://wiki.php.net/rfc/deprecations_php_8_5
👍54🤔12🔥105😱2
Пых
▶️ PHP-линч #24 Через час линч, не пропусти! https://youtu.be/WXJNj-b1ONk
Относительные имена

Если вы вдруг не знали, в PHP можно использовать namespace\, чтобы явно подставить текущий неймспейс в имя. Это альтернатива алиасам при наличии конфликта имён:


namespace Foo;

use Bar\Baz;

echo namespace\Baz; // выведет Foo\Baz


Вот пруф с 3v4l + на линче я подробно показал аналогичный пример. Также рекомендую прочитать статью документации про правила разрешения неймспейсов.

👾 Флешмоб!

Если у вас в ближайшее время возникнет ситуация, когда будет нужно использовать X из текущего неймспейса при наличии импорта X из другого неймспейса, напишите namespace\X вместо рефакторинга на алиас. В комментариях к посту поделитесь, заметили ли коллеги на ревью вашу шалость и пустили ли её в прод.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍48🔥16🤡11
Пыхап 8 ноября!

Друзья, ровно через 2 недели пройдёт первый в истории митап от канала Пых! В программе у нас 3 хардкорных доклада:

🤯 (Не) используйте функциональное программирование в PHP
Андрей Клименко поломает вам голову основами ФП и примерами на Scala, из которых станет понятно, что из функционального мира уже доступно в PHP, а что ещё предстоит законтрибьютить.

🐇 Вы не знаете RabbitMQ
Вадим Занфир расскажет, почему все современные фреймворки теряют сообщения и как на самом деле надо работать с "кроликом".

🤑 Как считать деньги и не терять их
В аду есть специальный котёл для тех, кто использует float для хранения денег. Сергей Жук подскажет, как в него не угодить.

Спонсор первого Пыхапа — моя любимая компания Happy Job 💚, где я проработал 4 года! Обращайтесь в Happy Job за исследованиями вовлечённости и оценкой 360, ребята делают лучшую платформу для развития сотрудников.

Пыхап пройдёт в уютном лофте «Событие» на Таганке, начало в 18:30. Вход бесплатный, но по билетам. Регистрация откроется на канале Пых в ближайший понедельник в 15:00, не пропустите. Ну и конечно же митап будет транслироваться на PHP Point с записью.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥98👍408🆒3
2025/07/08 20:15:38
Back to Top
HTML Embed Code: