Пых
В документации PHP
self, parent и static называются относительными типами классов (relative class types). С этой троицей мы боремся с самого начала. Каждый релиз — новый раунд.Раунд 1
Возьмём пару классов:
class A extends stdClass
{
public function self(): self { return $this; }
public function parent(): parent { return $this; }
public function static(): static { return $this; }
}
final class B extends A {}
С
self и parent здесь всё просто и однозначно: в классе A self = A, parent = stdClass, в класс B копируем эти 2 метода с уже разрешёнными типами A и stdClass. Значит, self и parent можно не оформлять как самостоятельные типы, а сразу заменять на конкретные классы из скоупа.Можем ли мы так же разрешить
static? Нет, так как это имя не текущего, а вызываемого класса (см. позднее статическое связывание): в A static резолвится как A, а в B — как B. При построении рефлексии мы должны в каждом унаследованном методе обновить static с учётом текущего скоупа. Для этого замоделируем static как first-class тип, который знает, где он сейчас находится, и получим typhoon/type 0.2:
A,B::self() возвращают types::object(A::class)
A,B::parent() возвращают types::object(stdClass::class)
A::static() возвращает types::static(A::class)
B::static() возвращает types::static(B::class)
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥2😐1
Пых
В Typhoon 0.3 я начал добавлять поддержку трейтов. И всё, естественно, поломалось.
Раунд 2
trait T
{
public function self(): self { return $this; }
public function parent(): parent { return $this; }
public function static(): static { return $this; }
}
Валидный ли это код? Да. Вот только ни один из трёх типов невозможно отрезолвить так же, как мы это делали выше.
self и parent не на что заменить, так как трейт сам по себе не является типом и не может наследовать другие. Для static отсутствует скоуп-класс.Нативная рефлексия, кстати, вообще не парится: всегда возвращает
ReflectionNamedType с 'self', 'parent' или 'static'. Мы так делать не хотим, потому что это просто откладывание проблемы на потом.Постепенно приходит понимание, что в трейтах относительные типы работают как плейсхолдеры. В Psalm и PHPStan их даже можно ограничивать через аннотации @require-extends и @require-implements. Всё это напоминает... дженерики!
Действительно,
/**
* @psalm-require-extends stdClass
* @phpstan-require-extends stdClass
*/
trait T
{
public function self(): self { return $this; }
public function parent(): parent { return $this; }
public function static(): static { return $this; }
}
final class A extends stdClass
{
use T;
}
можно с натяжкой переписать как
/**
* @template self of object
* @template parent of stdClass
* @template static of self
*/
trait T
{
public function self(): self { return $this; }
public function parent(): parent { return $this; }
public function static(): static { return $this; }
}
final class A extends stdClass
{
/**
* @use T<self, parent, self>
*/
use T;
}
Выглядит логично, но кривовато, потому что в реальности это не объявленные пользователем дженерики, а какие-то встроенные, да ещё и доступные в статике. Тем не менее, на тот момент идея мне очень нравилась, и, подставив пару костылей, я её реализовал в typhoon 0.3 и даже гордо рассказал про это на Стачке:
types::template('self', types::atClass(T::class))
types::template('parent', types::atClass(T::class))
types::template('static', types::atClass(T::class))
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥6😐1
Пых
Есть у меня одна черта: я периодически возвращаюсь ко всем своим костылям, пока не сделаю нормально
Раунд 3
final class A extends ArrayObject
{
public function self() { return fn (): self => new self(); }
public function parent() { return fn (): parent => new parent(); }
public function static() { return fn (): static => new static(); }
}
final class B extends stdClass {}
$self = (new A())->self();
echo $self()::class; // A
echo $self->call(new B)::class; // B
$parent = (new A())->parent();
echo $parent()::class; // ArrayObject
echo $parent->call(new B)::class; // stdClass
$static = (new A())->static();
echo $static()::class; // A
echo $static->call(new B)::class; // B
Получается, что
self, parent и static отлично себя чувствуют в анонимных функциях и, как и в трейтах, резолвятся в зависимости от скоупа, в том числе поддерживают его изменение в рантайме. Посмотрев на этот сниппет, мы наконец-то согласились, что относительные типы класса везде в PHP ведут себя логично и единообразно и должны быть замоделированы как first-class типы.Теперь в typhoon/type 0.4 можно создавать
self, parent и static с классом скоупа и без него. Последнее как раз требуется в трейтах и непривязанных анонимных функциях. В TypeVisitor каждый относительный тип обрабатывается индивидуально. Ну и, конечно, поддерживаются аргументы типов (а-ля self<X, Y>). Комбо-пример:
trait T
{
/**
* @return array{self, parent, static}
*/
public function types(): array
{
return [$this, $this, $this];
}
}
abstract class A extends stdClass
{
use T;
}
final class B extends A {}
$type = TyphoonReflector::build()
->reflectClass(B::class)
->methods()['types']
->returnType();
echo stringify($type);
// array{self@A, parent@stdClass, static@B}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥3🤔2
Традиционно после 0.X релиза Typhoon я запускаю X-й поток курса! Сегодня
X = 4.Набор на четвёртый поток будет осуществляться как обычно. Завтра (в среду, 7 августа) в 15:00 по Москве на канале Пых появится ссылка на срез знаний. Необходимо его пройти, чтобы попасть на курс. При проверке я сначала отберу анкеты с правильными ответами, а затем отранжирую их по времени. Удачи!
Обновлённая страничка курса: hardcorephp.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥36👍16❤5🥱3😢1
Пых
https://forms.gle/PFvHT7vujHEPuSs29
Удачи!
Please open Telegram to view this post
VIEW IN TELEGRAM
Google Docs
Срез знаний для 4-ого потока Хардкорного курса PHP
Привет! При проверке я сначала буду отбирать анкеты с правильными ответами и здравыми рассуждениями, а потом ранжировать их по времени. Не старайся ответить академично, лучше поясни своими словами или приведи хороший пример. Удачи!
🔥17🤡9👍5🤯1
Пых
Теперь, когда первая сотня абитуриентов прислала анкеты, предлагаю всем подумать над внеконкурсным заданием. Решите 5-ю задачу с теми же вводными в обратную сторону. То есть у вас должен получиться класс, который, наоборот, позволит использовать
Psr\Middleware как Symfony\Subscriber. Идеи можно обсуждать в комментариях к этому посту. Позже всё разберём на стриме.Gist с полной формулировкой этого варианта задачи: https://gist.github.com/vudaltsov/dc4f372692d2eabbc8c3d29cd4de0ccd
Навеяно, кстати, весьма драматическими событиями. В 2018-м году сообщество Symfony активно обсуждало невыполнение PHP-FIG своей "framework interoperability" миссии, так как компоненты HttpFoundation и HttpKernel нельзя малой кровью адаптировать под PSR-7. Апогеем стал pull-request Фабьена "Remove Symfony" в PHP-FIG. Тогда же у Symfony появился
Please open Telegram to view this post
VIEW IN TELEGRAM
Gist
symfony_to_psr.php
GitHub Gist: instantly share code, notes, and snippets.
👍8❤2🔥2
Пых
Сначала Вадим верно подметил, что суть решения сводится к приостановке потока управления внутри
Middleware и предложил использовать для этого генераторы. Затем Александр скинул прототип на базе файберов.Ну а вот полное решение с использованием
Fiber и WeakMap, которое я зафиксировал вскоре после публикации задачи: код, 3v4l. Обсудим подробнее на разборе среза знаний!P.S.: Всем спокойной ночи!
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Vadim Dvorovenko in Пыхтелка
В общем, тут вопрос в управлении потоком обработки в php. Всякую многопоточность откидываем, думаю решение нужно искать где-то в промисах и генераторах. Пока ставлю на yield, он вроде бы должен идеально подходить для того, чтобы прервать поток выполнения…
🔥22👍10❤3🤮1
Benchmarking Laravel with Swoole, FrankenPHP, RoadRunner, php-fpm, and ngx-php
https://youtu.be/ZB129Tjkas8
https://github.com/pronskiy/ngx-php_laravel
Позавчера Рома Пронский выложил новый ролик, в котором он забенчмаркал запуск Laravel через основные популярные рантаймы (php-fpm, RoadRunner, Swoole, FrankenPHP) + малоизвестный проект ngx-php, который по результатам Web Framework Benchmarks оставляет позади даже Swoole и workerman.
https://youtu.be/ZB129Tjkas8
https://github.com/pronskiy/ngx-php_laravel
Позавчера Рома Пронский выложил новый ролик, в котором он забенчмаркал запуск Laravel через основные популярные рантаймы (php-fpm, RoadRunner, Swoole, FrankenPHP) + малоизвестный проект ngx-php, который по результатам Web Framework Benchmarks оставляет позади даже Swoole и workerman.
YouTube
Benchmarking Laravel with Swoole, FrankenPHP, RoadRunner, php-fpm, and ngx-php
I've set up ngx-php to run Laravel example application in worker mode with Octane and then compared the performance with classic php-fpm and also other Octane drivers like FrankenPHP, Swoole, and RoadRunner.
The code and results are available here:
http…
The code and results are available here:
http…
👍21🔥16❤7
Пых
Назови несколько принятых в PHP 8.4 изменений.
Изменено значение у констант
PHP_VERSION и PHP_MINOR_VERSIONПочему некоторые расширения, например, ext-pcntl, в composer.json принято прописывать с констрейнтом "*"?
Звёздочка обычно означает примечание, сноску на полях. Возможно, для таких расширений автор прописывает потом примечания автора. Ну, типа, "добавлю-ка я
pcntl, сорян виндузятники, но вы идёте лесом".По какому принципу выбраны значения констант ReflectionProperty::IS_*?
Ребята решили ради прикола написать
1 << 1, 1 << 2, 1 << 3, и т.д., чтобы никто не понял что это значит.Можно ли расширить возвращаемый тип метода в дочернем классе и почему?
Конечно можно! Ни одной статьи в Конституции РФ или Кодексах за нарушение подобного не предусмотрено. Да и это не такое порицаемое обществом занятие, чтобы ещё за него кто-то осуждал. Всё в рамках приличия.
Как соотносятся понятия "полиморфизм" и "наследование"?
Они оба на написаны кириллицей и в кавычках (только "наследование" хуже, т.к. в нём 12 букв, а "полиморфизм" в этом плане меньше весит, т.к. всего 11 букв).
Интересный факт: Если написать эти слова наоборот, то получится "мзифромилоп" и "еинаводелсан", но их размер не изменится. А ещё из букв в слове "полиморфизм" можно составить слово "зоофил", а из слова "наследование" можно составить "лениновед".
Теперь ты тоже будешь знать это!
Реши задачу.
final readonly class SymfonyIntegrator
{
public function integrate(): void
{
$previous = \getcwd();
try {
\chdir(__DIR__);
\copy('https://getcomposer.org/installer', __DIR__ . '/composer-setup.php');
require __DIR__ . '/composer-setup.php';
new \Symfony\Component\Process\Process([
\PHP_BINARY,
__DIR__ . '/composer.phar',
'create-project',
'symfony/skeleton',
])->run();
// Больше нам PSR фреймворк не нужен
} finally {
$previous && \chdir($previous);
}
}
}
Почему попросить ИИ-помощника написать тесты может быть не очень хорошей идеей?
Нельзя показывать работодателю, что всю твою работу может заменить скрипт на питоне.
В чём оптимизм оптимистичной блокировки?
Разработчики надеются, что в конце-концов когда-нибудь блокировка разблокируется, всё наладится и все будут жить долго и счастливо.
Что ждёшь от курса?
Ну хотя бы доллар по 25, как в началах 2000х. Был бы норм курс.
Please open Telegram to view this post
VIEW IN TELEGRAM
😁151👍22🤡12👏4❤2🥴2🦄1
Все студенты получили письма с приглашениями на почту.
Немного статистики и наблюдений:
▸ 108 ответов на момент написания этого поста.
▸ 20 человек набралось на 64-й анкете (в прошлый раз на 41-й), она была отправлена через 54 минуты после старта.
▸ Как будто бы в этот раз вы чаще прибегали к помощи чат-ботов. Некоторые ответы были слишком вышколенными и высокопарными. Программист, который на скорость проходит опрос, так никогда не напишет. В решении 5-й задачи некоторые даже оставили типовые комментарии. В общем, когда я видел явные признаки использования ИИ, я переходил к следующему ответу. И наоборот, к тем, кто по-человечески ошибался в тексте или коде, я был более внимателен.
Сегодня (9 августа) в 19:00 разберём срез и задачу со звёздочкой, приглашаю всех на стрим!
https://youtu.be/wGegvTFidaA
P.S.: Форму не буду закрывать в демонстрационных целях. Заполняйте сколько хотите или используйте на собесах.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥8❤1👎1🤡1
Думаю, никому не нужно представлять языковую конструкцию eval. В 2024 все пыхари знают её как древнее могущественное зло, которое ни при каких условиях не должно оказаться на проде. Если в проекте есть хоть один
eval, он автоматически считается Такое отношение к
eval непоследовательно. Если вы используете Symfony Dependency Injection, Doctrine ORM, Ocramius Proxy Manager или любой другой пакет с кодогенерацией, вы фактически используете eval, только завуалированный. С точки зрения безопасности нет никакой разницы между тем, чтобы выполнить код из строки, и тем, чтобы сначала записать строку в файл, а затем его выполнить.Что на самом деле важно
1. При использовании
eval и кодогенерации нужно 1000 раз убедиться, что входные данные либо вообще не могут попасть в код, либо строго санитизируются и правильно интерполируются с использованием var_export() или Typhoon Exporter.2. Код, исполняемый через
eval, require и include получает доступ к текущей области видимости и переменным. Для изоляции можно обернуть вызов в статическое замыкание, см. пример.На десерт. В коде Symfony 7 есть eval. И не один... А как минимум 3... Уверен, что почти в каждом фреймворке есть. Поищите и скиньте в комментарии.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍54🔥10🤔7❤2🌚2🙏1👀1
Forwarded from PHP Fart Time (Алексей roxblnfk)
triangular-octopus-0f6 on Notion
В мире PHP #2 | Notion
Сорян, фартаны. Статейку чутка просрочил. Заработался, бывает. Представьте, что она опубликована месяц назад и баянов тут нет.
Новый выпуск "В мире PHP"
https://triangular-octopus-0f6.notion.site/PHP-2-d67a1f346b8541729fb3aa476e0fa086?pvs=4
⬆️ предыдущая часть
#Article #PHP #МыслиВслух
https://triangular-octopus-0f6.notion.site/PHP-2-d67a1f346b8541729fb3aa476e0fa086?pvs=4
⬆️ предыдущая часть
#Article #PHP #МыслиВслух
1👍29🔥11❤9
Пора возобновить наши встречи! Жду всех в эту среду в
18:30 по Москве.Одна заявка на линч у меня уже есть от Сергея Предводителева: vjik/telegram-bot-api. Пишите в комментариях, что ещё хотите посмотреть.
https://youtu.be/zuGtL5u2lsY
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
PHP-линч #22 • vjik/telegram-bot-api
Внимание! Чтобы YouTube опубликовал ваш комментарий, пишите не полный URL, а, например, symfony/console.
Как устроен PHP-линч:
1. Во время стрима вы скидываете в чат трансляции ссылки на репозитории и в трёх словах описываете, что там. Это может быть ваш…
Как устроен PHP-линч:
1. Во время стрима вы скидываете в чат трансляции ссылки на репозитории и в трёх словах описываете, что там. Это может быть ваш…
5🔥45👍7
Надо ли нам запускать альтернативную платформу для вещания?
Anonymous Poll
15%
Да! Сейчас в комментариях напишу, что предпочитаю.
57%
Нет. Только YouTube, только хардкор.
29%
Мне всё равно! Готов смотреть где угодно.
👍7
Podlodka PHP Crew «Практическая архитектура»
На следующей неделе стартует пятая Podlodka PHP. Программа:
• Упорядочиваем хаос: архитектурная документация по модели C4 / Кирилл Сурогатов
• Как стать x2 разработчиком, используя явное состояние / Кирилл Мокевнин
• Нам уже нужен CQRS? А теперь? /💙 Валентин Удальцов
• PHP + Prometheus: Работа с кастомными метриками / Алексей Солодкий
• RabbitMQ vs Kafka: обрабатываем большие объёмы / Михаил Каморин
• Построение качественных банковских интеграций на PHP / Дмитрий Кириллов
• PHP будет долго жить: переезжаем на Roadrunner / Владимир Плахотников
• Нет ничего более постоянного, чем Temporal /🔥 Павел Бучнев, Алексей Гагарин
• Перевозим приложение на PHP в Kubernetes / Вадим Дворовенко
Сегодня последний шанс купить билет по сниженной цене. По промокоду
https://podlodka.io/phpcrew
На следующей неделе стартует пятая 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
podlodka.io
Онлайн-конференция Podlodka PHP Crew, сезон #8
Недельное мероприятие от команды Podlodka: ежедневные интерактивные сессии в Zoom по актуальным вопросам PHP-индустрии, нон-стоп общение с экспертами и звёздами индустрии, закрытое профессиональное сообщество в Telegram.
5👍21🔥11❤1🥴1
Контекст в PSR-3 Logger
Периодически сталкиваюсь с неправильным использованием
Жирным выделил то, что многие упускают: вы можете передавать в контекст абсолютно любые значения, в том числе массивы, объекты, замыкания и ресурсы. Не нужно самостоятельно проводить нормализацию. По стандарту это задача логгера, а не ваша. Вот как, например, Monolog обработает контекст со сложными элементами:
Исключения нужно добавлять в контекст с ключом
Ну и конечно же не забывайте про плейсхолдеры в сообщении. Вместо интерполяции и
Периодически сталкиваюсь с неправильным использованием
$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 charactersA-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"} []
www.php-fig.org
PSR-3: Logger Interface - PHP-FIG
We're a group of established PHP projects whose goal is to talk about commonalities between our projects and find ways we can work better together.
6👍136🔥39❤9
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://t.me/live_php_news/27
В этот четверг в Санкт-Петербурге пройдёт очередной Live PHP. Вот мои ожидания от докладов.
• GIGA IDE Cloud - сверхновая IDE во вселенной веб-разработки. Хочу послушать из первых уст про успехи Сбера на поприще IDE. Пора искать замену PhpStorm.
• Transaction Script и Transaction Outbox в PHP: Эффективные паттерны для управления транзакциями. В моей картине мира Transaction Script и Transaction Outbox — это как гранатовый сок и гранатовый браслет. Интересно узнать, как Станислав уместил две ортогональные концепции в один доклад.
• Страх и ненависть PSR. Недавно с Кириллом Мокевниным (интервью выйдет в октябре) обсуждали, что, несмотря на все проблемы, PHP всё-таки смог в стандарты в отличие от многих других языков. Качественный наброс от Кирилла Несмеянова будет очень кстати. С нетерпением жду!
• Как растут проекты. Дима Елисеев, с удовольствием послушаю любые твои мысли, только, пожалуйста, не затягивай.
Короче, я взял билеты на Сапсан 🚝, и в четверг в 18:30 буду как штык в IT-баре Failover.
https://t.me/live_php_news/27
Please open Telegram to view this post
VIEW IN TELEGRAM
Яндекс Карты
Больше не работает: Failover, бар, Санкт-Петербург, 4-я Советская улица, 7 — Яндекс Карты
115 отзывов, 92 фото. Посмотреть номер телефона и построить маршрут вы можете в Яндекс Картах.
🔥19👍7❤4🐳2
Через два часа выступаю на Podlodka PHP Crew!
Сегодняшний доклад — результат недавнего переосмысления многочисленных статей и выступлений Udi Dahan про CQRS, наложенный на мой опыт примения и преподавания этого архитектурного стиля.
Мне бы хотелось показать вам CQRS с нестандартного ракурса. Посмотрим, что у меня получится.🤫
Кстати, я всегда был убеждён, что отец CQRS — только Greg Young, но оказалось, что Udi тоже к этому причастен:
Сегодняшний доклад — результат недавнего переосмысления многочисленных статей и выступлений 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🐳4❤1
Как и обещал, буду стараться делать линчи по средам. Сегодня предлагаю встретиться пораньше, в
18:00, чтобы вы успели на Podlodka.https://youtu.be/FYVfQk0-t3U
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
PHP-линч #23 • savinmikhail/Comments-Density
Внимание! Чтобы YouTube опубликовал ваш комментарий, пишите не полный URL, а, например, symfony/console.
Как устроен PHP-линч:
1. Во время стрима вы скидываете в чат трансляции ссылки на репозитории и в трёх словах описываете, что там. Это может быть ваш…
Как устроен PHP-линч:
1. Во время стрима вы скидываете в чат трансляции ссылки на репозитории и в трёх словах описываете, что там. Это может быть ваш…
2🔥27👍7❤4😁1
В последний момент исправляю рефлексию в PHP 8.4!
На неделе я начал добавлять поддержку PHP 8.4 в Typhoon Reflection, и очень рад, что взялся за это до релиза.
Во-первых, я зарепортил отсутствие обещанной в RFC хуков константы
А вот что меня реально загрузило, так это поведение новых методов
Сначала я подумал, что это баг, и создал тикет php-src#16175. Ilija, автор RFC, объяснил, почему так работает. Дело в том, что у свойств с симметричной видимостью отсутствует флаг ассиметричности. Поэтому для
Стало понятно, вот только пользоваться такой рефлексией по-прежнему дико неудобно. В API протекли детали реализации, которые, наоборот, должны быть инкапсулированы. Задача рефлексии — предоставить пользователю комфортный способ изучать код, а не продемонстрировать подкапотное устройство языка.
Но это ещё ладно. Сегодня до меня дошло, что в текущем виде рефлексия в PHP 8.4 ломает обратную совместимость! Если раньше проверка
Например, такой код корректно отработает для любых классов в PHP 8.3, но споткнётся на
Вот что я предложил в письме к internals, которое составил в Сапсане по дороге на Live PHP:
•
• Добавить
• Добавить
Вся проблема в том, что недавно вышел PHP 8.4 RC1, и вносить изменения уже поздно. Надеюсь, что мой посыл про нарушение обратной совместимости всё-таки убедит сделать исключение.
На неделе я начал добавлять поддержку 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, и вносить изменения уже поздно. Надеюсь, что мой посыл про нарушение обратной совместимости всё-таки убедит сделать исключение.
externals.io
Asymmetric visibility Reflection API problems - Externals
#externals - Opening PHP's #internals to the outside
5👍45🤯37🔥14❤1