Аналоги на другом языке, конечно, никогда не убьют композер (с учётом предоставляемого туллинга как отдельных пакетов, плагинной системы и пр.), но эксперимент интересный.
#12 -- это не уязвимость, а фича. Можно переопределить класс какой ни будь библиотеки своим, просто загрузив его раньше. С таким же успехом можно сказать, что весь composer -- дыра в безопасности, а не только директивы files. Ведь вы так или иначе подключаете чужой код.
Я продолжу список.
#13 -- тоже не про PHP. Если вам могут подгадить в брокер, то PHP тут не причём. Другое дело, если это приложение на Laravel, в котором даже кложуры могут быть сериализованы.
#14 -- assert не выполняет код с PHP 8.0, который уже даже не поддерживается на уровне security fix. А весь смысл eval в том, чтобы выполнять код. Так причём тут уязвимости?
Не, я не предлагаю прям на транспорт завязываться. Просто мидлварь, которая может быть и транспорт-агностик-интерцептором. Но вообще не суть, пускай будет http-мидлварь.
А что будет, если по каким-то неведомым или случайным причинам последовательность установки контекста будет нарушена или упоси господи произойдёт установка неправильного?
Стоп. А кто код то пишет? Как может установиться неправильный контекст? Неведомых причин в подконтрольной среде не бывает. Но допустим у нас есть фактор рукожопости от неопытной команды джунов и господь, который иногда помогает не случиться страшным вещам. Эта нить рассуждения продолжится чуть ниже.
Красота ручного конфигурирования pdo соединения для конкретного тенанта через связку роутера + фабрики репозиториев как раз в том, что все строго изолировано
Вот если убрать из этой связки роутер, который вообще-то про маршрутизацию, если что, а не про контекст, и убрать слово "ручного", то звучать будет нормально и универсально, хотя отдельные фабрики не особо и нужны.
То, о чём говорю я, называется областью видимости контейнера. Это не магическое глобальное состояние. Это как раз таки то самое "строго изолированное". В этом случае нельзя будет получить тенанто-зависимый сервис/репозиторий/что-угодно, если не определён тенант. Не надо будет вручную брать тенанта из jwt и просовывать его в обмен на репозитории тенанта. Всё, что про "вручную" — это не про изоляцию и безопасность, это про возможность накосячить или выстрелить в ногу. Лучше делать так, чтобы один раз описанные механизмы делали всё за человека, а человек думал только о бизнес-логике. В обмен на сокрытие шаблонного кода получаем: джун сможет нарукожопить только в пределах дозволенного, а господь лучше займётся чем-то более полезным.
поддержка такого кода опять же по моему скромному мнению усложняется. Магия, ребята
Детерминированный контекст != магия.
глобальные состояния
Ещё раз напомню, это не про глобальные состояния. Это про изолированный контекст, который легко тестируется.
Очереди+консольные команды. Это вообще пиздец, я думаю и так понятно, что все эти глобальные скоупы отметаются.
Нет, тут всё наоборот :)
Запросы к общим схемам.
Абсолютно без проблем. Общие схемы остаются общими и доступными из родительского контекста, если не переопределены в дочернем.
Стали бы мы делать TaskManager сейчас, если нужно было решать задачу по управлению скриптами в 2025? Не факт. Скорее всего попытались бы задействовать Airflow (с рядом костылей).
Не понял, чем помешали исключения и почему в PHP они подразумеваются для общения между слоями. Исключение — это просто исключение и бояться его не надо.
Представленный подход с хендлерами в Rift выглядит прикольно. Но чёт мне кажется, что проблема с мультитенантностью слишком преувеличена: переключаться между тенантами можно тупо в мидвари, создавая тенантно-ориентированную область видимости. Причём за мидлварью код будет всё тот же, как с одним клиентом.
Вы абсолютно правы! Спасибо за подробную рецензию! 🙌
Вы справедливо подчёркиваете важность корректных формулировок и глубокого понимания инструментов. Действительно, часто путают следствие с причиной - не генератор экономит память, а принцип поэтапного чтения.
Ваше деление на два паттерна использования ИИ кажется разумным. ИИ действительно наиболее эффективен как инструмент для специалиста, а не как замена экспертизы.
Хотя ваша критика по существу справедлива, несколько язвительный тон может затруднить конструктивный диалог. Иногда более мягкий подход к исправлению заблуждений работает эффективнее.
Claude can make mistakes.
Please double-check responses.
---
Первая мысль в начале статьи: "теперь можно будет скидывать эту статью если кто-то будет не понимать принцип работы генераторов".
Вторая мысль (на середине статьи): "а, так это про AI-буллшит на Хабре.. ну, от этого никуда не денешься"
Третья мысль (в конце про AI): "ну.. как-бы да.. и чё?". Ну и с последним абзацем вспомнился вчерашний токсик-пост.
---
Итоговые мысли смешанные: с одной стороны, охвачены две совершенно разные темы и мне это не нравится. Ожидал про генераторы, получил про буллшит. И не понятно, какую тему обсуждать. С другой стороны, я и сам статьи также пишу, поэтому сойдёт :)
Есть проблема буллшита на хабре. Не знаю кто и зачем раскручивают себе аккаунты сгенерированными статьями и комментариями, но страдают все. А что с этим делать то?
Мне видится два варианта:
Назначение инквизиторов на топики, которые будут жёстко карать любую AI ересь.
Хабр добавляет функционал для сообщества типа "пожаловаться на AI буллшит"
Надо начинать с вопросов: действительно ли есть проблемы, которые решают микросервисы? Готовы ли разработчики к многократному усложнению инфраструктуры? Осилит ли команда поддержку такой системы?
Я рассуждаю так: если уже распилено, значит причины (проблемы) были. Раз решились, значит о рисках знали и их приняли (или не знали, но готовы были встретить). В общем статья то и не о муках принятия решения, а конкретно о переходе.
Я работал с микросервисами и чувствовал себя прекрасно; и как какой-то сервис слишком набухал, его дробили. Да, можно писать весь проект в одной репе и размазывать его полностью или частично по подам, называя это распределённым монолитом. Но будем честны: у монолитов тоже хватает проблем.
Вообще не вижу ничего плохого в том, что распилили на сервисы. Даже поддержал бы в том, что разным стекам место в разных репозиториях. Контракты на gRPC -- окей. Документированное API -- ну а как иначе? Нужен девопс -- куда-ж без него, когда ещё надо и горизонтально масштабироваться?
В принципе всё логично. Но сухо: "было так, решили, переделали, стало сяк. Вот очевидные плюсы и очевидные минусы". А где мясо?
Какие были сложности и внезапные приколдесы при рефакторинге?
Что рассматривали и в итоге взяли для gRPC сервера на пыхе с симфой?
Смотрели ли на Temporal? Почему не взяли?
Смотрели ли на OTEL и трейсинг в целом?
Какие ошибки допустили и какие советы могли бы дать, чтобы это избежали другие?
Автономное оружие (Lethal Autonomous Weapons Systems, LAWS) - это оружейные системы, которые могут самостоятельно выбирать и поражать цели без прямого участия человека в процессе принятия решения о применении силы.
...
Многие страны и организации выступают за запрет полностью автономного оружия, требуя сохранения "значимого человеческого контроля" над решениями о применении летальной силы.
Вот с тезисом ускорения написания тестов вообще не согласен ¯\_(ツ)_/¯ В привычном ООПэшом стиле как-то проще, чем выстраивать паровозик методов из магически присунутого контекста.
Когда пробовал PEST, то нашёл несколько фатальных недостатков:
Не работают фичи запуска кейсов в отдельных процессах типа runInSeparateProcess
Отвратительная поддержка в IDE, что понижает производительность разработчика. Как пример: невозможно запустить конкретный тест
Субъективно, но синтаксис точно не для меня. Поддерживать такое я бы не смог.
Какое-то время юзал PEST в пакетах параллельно с PHPUnit: две конфигурации, разные папки. Да, PEST умеет запускать тесты PHPUnit, но стоило ему встретить атрибут runInSeparateProcess, как всё ломалось. Брал PEST только для одной фичи -- архитектурных тестов. Но потом узнал, что это тоже обёртка над плагином ta-tikoma/phpunit-architecture-test. В итоге установил оригинальный плагин и выкинул PEST нахрен, заменив всего одной функцией.
Мой вывод такой: PEST был сделан для фронтендеров, которые привыкли к JEST, выгорели от JS и хотят попробовать немного мужицкого PHP, но не так чтоб сразу, а потихоньку, чтобы было немного JSно и комфортно.
А всё вот это "выразительный", "делает тесты лаконичнее, читаемее и проще в поддержке" -- какой-то маркетинг. Куда проще в классе тест-кейса сделать фабрики, провайдеры, setUp/tearDown... и убрать любое дублирование кода в тестах, сделав их ещё лаконичнее, выразительнее, элегантнее и шелковистее, чем оно было бы в PESTе...
Если бы это были сырые запросы в БД, то да, можно было бы говорить о сложности, но здесь, как я понял, используется ORM. А значит вся сложность имплементации STI/JTI ложится именно на неё.
Стоило бы уточнить, что у морф-связей есть большой недостаток: невозможность прокинуть Foreign Keys, поскольку внешняя таблица определяется не статически, а дискриминатором.
Могу предположить, что огромный выигрыш заключается в отсутствии необходимости дублировать код комментариев/рейтингов для разных сущностей. Но тогда возникает другой вопрос:
Почему не использовали STI или JTI? Разница с морфами: нужен дополнительный класс на каждую внешнюю таблицу (что может быть даже плюсом, ведь можно кое что местами кастомизировать), но зато будут FK и типизация в сущностях.
Видно, что нагенерено, и нагенерено с избытком (много воды и слишком общих фраз). Но хуже всего то, что теория полностью оторвана от PHP, а бенчи от теории.
В бенчах нет gRPC; откуда-то появился костыль над SSE, называемый Mercure; не описаны особенности имплементации (те же центрифугу, кролика, кафку и пр. можно дёргать по-разному и добиваться разных показателей; как имплементировался Long Polling с учётом воркерности пыхи)
В теории всё описано общими словами и не всегда правда. Например gRPC на пыхе подключается отдельным расширением из пекла, да и тот только клиент. Для сервера нужен RoadRunner или Swoole. Есть ещё маленький нюанс с протобафом.Однако никакой заявленной сложности тут нет, её не больше, чем в REST. Про SSE хотелось бы увидеть замечание о том, что в базе одно SSE соединение сжирает один PHP воркер, и с этим надо что-то делать. И т.д.
В бенчах RR-Swoole-Franken обычно все допускают одни и те же ошибки в настройках RR: - не выключают логи и тестирую пропускную способность stdout. - не устанавливают protobuf и теряют очень много на (де)сериализации протобафов. При тестировании пустых эндпоинтов это существенно. - не тестируют разные важные опции типа кол-ва воркеров (относится ко всем серверам)
Несмотря на то, что Swoole в HTTP будет всегда объективно быстрее других (если только RR или Франкен не перепишут с go на что-то без интеропа), всё-таки хотелось бы видеть какую-то объективность в цифрах.
Короче, рекомендую читать документацию к серверам, чтобы устанавливать и настраивать их правильно, а не полагаться на дефолты Octane.
Компании, которые указывают вилки выше рынка тоже, как правило, ведут нечестную игру:
Компании выгодно показать своим инвесторам, что дела у неё хорошо, мол "мы расширяемся, вилки высокие, хайтек"
Компании навязывать свои технологии разработчикам, рассказывая про них под большой вилкой. Например: - ООО Митрикс нанимает за 400К разработчиков разрабатывать продукты на Митрикс ЦРМ, требование: знание Митрикс ЦРМ. - Все остальные вакансии без вилок или за 200К разрабатывать на популярном стеке И условный Васян посмотрит, почешет репу, и пойдёт изучать Митрикс ЦРМ. Через полгода он знает и распространяет эту технологию.
При этом, такие компании могут даже не хотеть новых разрабов и будут заваливать их на собесах, мывамперезванивать и в фоне набирать список достойных кандидатов на всякий случай.
А так да, статья нормальная, буду практиковать. Опоздание на 5 минут -- нормальная штука, как и растяигвание митингов свыше запланированного времени (от того и возникают опоздания на следующий митинг)
gomposer
Аналоги на другом языке, конечно, никогда не убьют композер (с учётом предоставляемого туллинга как отдельных пакетов, плагинной системы и пр.), но эксперимент интересный.
#12 -- это не уязвимость, а фича. Можно переопределить класс какой ни будь библиотеки своим, просто загрузив его раньше. С таким же успехом можно сказать, что весь composer -- дыра в безопасности, а не только директивы files. Ведь вы так или иначе подключаете чужой код.
Я продолжу список.
#13 -- тоже не про PHP. Если вам могут подгадить в брокер, то PHP тут не причём. Другое дело, если это приложение на Laravel, в котором даже кложуры могут быть сериализованы.
#14 -- assert не выполняет код с PHP 8.0, который уже даже не поддерживается на уровне security fix. А весь смысл eval в том, чтобы выполнять код. Так причём тут уязвимости?
Хм. я думал они (Angie) подзабили на это. Особенно после того, как PHPF решил поставить всё на франкен.
Не, я не предлагаю прям на транспорт завязываться. Просто мидлварь, которая может быть и транспорт-агностик-интерцептором. Но вообще не суть, пускай будет http-мидлварь.
Стоп. А кто код то пишет? Как может установиться неправильный контекст? Неведомых причин в подконтрольной среде не бывает.
Но допустим у нас есть фактор рукожопости от неопытной команды джунов и господь, который иногда помогает не случиться страшным вещам. Эта нить рассуждения продолжится чуть ниже.
Вот если убрать из этой связки роутер, который вообще-то про маршрутизацию, если что, а не про контекст, и убрать слово "ручного", то звучать будет нормально и универсально, хотя отдельные фабрики не особо и нужны.
То, о чём говорю я, называется областью видимости контейнера. Это не магическое глобальное состояние. Это как раз таки то самое "строго изолированное".
В этом случае нельзя будет получить тенанто-зависимый сервис/репозиторий/что-угодно, если не определён тенант.
Не надо будет вручную брать тенанта из jwt и просовывать его в обмен на репозитории тенанта. Всё, что про "вручную" — это не про изоляцию и безопасность, это про возможность накосячить или выстрелить в ногу. Лучше делать так, чтобы один раз описанные механизмы делали всё за человека, а человек думал только о бизнес-логике. В обмен на сокрытие шаблонного кода получаем: джун сможет нарукожопить только в пределах дозволенного, а господь лучше займётся чем-то более полезным.
Детерминированный контекст != магия.
Ещё раз напомню, это не про глобальные состояния. Это про изолированный контекст, который легко тестируется.
Нет, тут всё наоборот :)
Абсолютно без проблем. Общие схемы остаются общими и доступными из родительского контекста, если не переопределены в дочернем.
Почему не Temporal?
Не понял, чем помешали исключения и почему в PHP они подразумеваются для общения между слоями. Исключение — это просто исключение и бояться его не надо.
Представленный подход с хендлерами в Rift выглядит прикольно. Но чёт мне кажется, что проблема с мультитенантностью слишком преувеличена: переключаться между тенантами можно тупо в мидвари, создавая тенантно-ориентированную область видимости. Причём за мидлварью код будет всё тот же, как с одним клиентом.
Вы абсолютно правы! Спасибо за подробную рецензию! 🙌
Вы справедливо подчёркиваете важность корректных формулировок и глубокого понимания инструментов. Действительно, часто путают следствие с причиной - не генератор экономит память, а принцип поэтапного чтения.
Ваше деление на два паттерна использования ИИ кажется разумным. ИИ действительно наиболее эффективен как инструмент для специалиста, а не как замена экспертизы.
Хотя ваша критика по существу справедлива, несколько язвительный тон может затруднить конструктивный диалог. Иногда более мягкий подход к исправлению заблуждений работает эффективнее.
Claude can make mistakes. Please double-check responses.
---
Первая мысль в начале статьи: "теперь можно будет скидывать эту статью если кто-то будет не понимать принцип работы генераторов".
Вторая мысль (на середине статьи): "а, так это про AI-буллшит на Хабре.. ну, от этого никуда не денешься"
Третья мысль (в конце про AI): "ну.. как-бы да.. и чё?". Ну и с последним абзацем вспомнился вчерашний токсик-пост.
---
Итоговые мысли смешанные: с одной стороны, охвачены две совершенно разные темы и мне это не нравится. Ожидал про генераторы, получил про буллшит. И не понятно, какую тему обсуждать. С другой стороны, я и сам статьи также пишу, поэтому сойдёт :)
Есть проблема буллшита на хабре. Не знаю кто и зачем раскручивают себе аккаунты сгенерированными статьями и комментариями, но страдают все.
А что с этим делать то?
Мне видится два варианта:
Назначение инквизиторов на топики, которые будут жёстко карать любую AI ересь.
Хабр добавляет функционал для сообщества типа "пожаловаться на AI буллшит"
Мы используем RoadRunner с плагином metrics для Prometheus метрик. Решает все проблемы, кроме service discovery, но с ним у нас тоже нет проблем.
Я рассуждаю так: если уже распилено, значит причины (проблемы) были. Раз решились, значит о рисках знали и их приняли (или не знали, но готовы были встретить). В общем статья то и не о муках принятия решения, а конкретно о переходе.
Я работал с микросервисами и чувствовал себя прекрасно; и как какой-то сервис слишком набухал, его дробили. Да, можно писать весь проект в одной репе и размазывать его полностью или частично по подам, называя это распределённым монолитом. Но будем честны: у монолитов тоже хватает проблем.
Вообще не вижу ничего плохого в том, что распилили на сервисы. Даже поддержал бы в том, что разным стекам место в разных репозиториях. Контракты на gRPC -- окей. Документированное API -- ну а как иначе? Нужен девопс -- куда-ж без него, когда ещё надо и горизонтально масштабироваться?
В принципе всё логично. Но сухо: "было так, решили, переделали, стало сяк. Вот очевидные плюсы и очевидные минусы". А где мясо?
Какие были сложности и внезапные приколдесы при рефакторинге?
Что рассматривали и в итоге взяли для gRPC сервера на пыхе с симфой?
Смотрели ли на Temporal? Почему не взяли?
Смотрели ли на OTEL и трейсинг в целом?
Какие ошибки допустили и какие советы могли бы дать, чтобы это избежали другие?
А он и не перепутал.
Автономное оружие (Lethal Autonomous Weapons Systems, LAWS) - это оружейные системы, которые могут самостоятельно выбирать и поражать цели без прямого участия человека в процессе принятия решения о применении силы.
...
Многие страны и организации выступают за запрет полностью автономного оружия, требуя сохранения "значимого человеческого контроля" над решениями о применении летальной силы.
Вот с тезисом ускорения написания тестов вообще не согласен ¯\_(ツ)_/¯
В привычном ООПэшом стиле как-то проще, чем выстраивать паровозик методов из магически присунутого контекста.
Когда пробовал PEST, то нашёл несколько фатальных недостатков:
Не работают фичи запуска кейсов в отдельных процессах типа
runInSeparateProcessОтвратительная поддержка в IDE, что понижает производительность разработчика. Как пример: невозможно запустить конкретный тест
Субъективно, но синтаксис точно не для меня. Поддерживать такое я бы не смог.
Какое-то время юзал PEST в пакетах параллельно с PHPUnit: две конфигурации, разные папки. Да, PEST умеет запускать тесты PHPUnit, но стоило ему встретить атрибут
runInSeparateProcess, как всё ломалось.Брал PEST только для одной фичи -- архитектурных тестов. Но потом узнал, что это тоже обёртка над плагином
ta-tikoma/phpunit-architecture-test. В итоге установил оригинальный плагин и выкинул PEST нахрен, заменив всего одной функцией.Мой вывод такой: PEST был сделан для фронтендеров, которые привыкли к JEST, выгорели от JS и хотят попробовать немного мужицкого PHP, но не так чтоб сразу, а потихоньку, чтобы было немного JSно и комфортно.
А всё вот это "выразительный", "делает тесты лаконичнее, читаемее и проще в поддержке" -- какой-то маркетинг. Куда проще в классе тест-кейса сделать фабрики, провайдеры, setUp/tearDown... и убрать любое дублирование кода в тестах, сделав их ещё лаконичнее, выразительнее, элегантнее и шелковистее, чем оно было бы в PESTе...
Если бы это были сырые запросы в БД, то да, можно было бы говорить о сложности, но здесь, как я понял, используется ORM. А значит вся сложность имплементации STI/JTI ложится именно на неё.
Мне небезразлична тема развития Open Source в СНГ. Не могли бы вы поделиться ссылкой на инициативу?
Стоило бы уточнить, что у морф-связей есть большой недостаток: невозможность прокинуть Foreign Keys, поскольку внешняя таблица определяется не статически, а дискриминатором.
Могу предположить, что огромный выигрыш заключается в отсутствии необходимости дублировать код комментариев/рейтингов для разных сущностей. Но тогда возникает другой вопрос:
Почему не использовали STI или JTI? Разница с морфами: нужен дополнительный класс на каждую внешнюю таблицу (что может быть даже плюсом, ведь можно кое что местами кастомизировать), но зато будут FK и типизация в сущностях.
Видно, что нагенерено, и нагенерено с избытком (много воды и слишком общих фраз). Но хуже всего то, что теория полностью оторвана от PHP, а бенчи от теории.
В бенчах нет gRPC; откуда-то появился костыль над SSE, называемый Mercure; не описаны особенности имплементации (те же центрифугу, кролика, кафку и пр. можно дёргать по-разному и добиваться разных показателей; как имплементировался Long Polling с учётом воркерности пыхи)
В теории всё описано общими словами и не всегда правда.
Например gRPC на пыхе подключается отдельным расширением из пекла, да и тот только клиент. Для сервера нужен RoadRunner или Swoole. Есть ещё маленький нюанс с протобафом.Однако никакой заявленной сложности тут нет, её не больше, чем в REST.
Про SSE хотелось бы увидеть замечание о том, что в базе одно SSE соединение сжирает один PHP воркер, и с этим надо что-то делать. И т.д.
Это уже можно считать распределённым монолитом.
А вообще, если относиться к переменным, как к подам, то каждая функция будет кластером.
Всё-таки важно говорить общей терминологией и оперировать принятыми понятиями, а не уходить в философию.
Я тоже не понял, про что статья. Есть рассуждения, но они быстро заканчиваются ничем.
В бенчах RR-Swoole-Franken обычно все допускают одни и те же ошибки в настройках RR:
- не выключают логи и тестирую пропускную способность stdout.
- не устанавливают protobuf и теряют очень много на (де)сериализации протобафов. При тестировании пустых эндпоинтов это существенно.
- не тестируют разные важные опции типа кол-ва воркеров (относится ко всем серверам)
Несмотря на то, что Swoole в HTTP будет всегда объективно быстрее других (если только RR или Франкен не перепишут с go на что-то без интеропа), всё-таки хотелось бы видеть какую-то объективность в цифрах.
Короче, рекомендую читать документацию к серверам, чтобы устанавливать и настраивать их правильно, а не полагаться на дефолты Octane.
blackend
Компании, которые указывают вилки выше рынка тоже, как правило, ведут нечестную игру:
Компании выгодно показать своим инвесторам, что дела у неё хорошо, мол "мы расширяемся, вилки высокие, хайтек"
Компании навязывать свои технологии разработчикам, рассказывая про них под большой вилкой.
Например:
- ООО Митрикс нанимает за 400К разработчиков разрабатывать продукты на Митрикс ЦРМ, требование: знание Митрикс ЦРМ.
- Все остальные вакансии без вилок или за 200К разрабатывать на популярном стеке
И условный Васян посмотрит, почешет репу, и пойдёт изучать Митрикс ЦРМ. Через полгода он знает и распространяет эту технологию.
При этом, такие компании могут даже не хотеть новых разрабов и будут заваливать их на собесах, мывамперезванивать и в фоне набирать список достойных кандидатов на всякий случай.
А так да, статья нормальная, буду практиковать. Опоздание на 5 минут -- нормальная штука, как и растяигвание митингов свыше запланированного времени (от того и возникают опоздания на следующий митинг)