Как стать автором
Обновить
3
Карма
0
Рейтинг

Пользователь

  • Подписчики
  • Подписки

PHP Дайджест № 210 (16 – 30 августа 2021)

Хотелось бы чтобы все основные части фрэймворков были бы полностью взаимозаменяемыми.

Разные фреймворки потому и появляются, что у людей разное видение на хороший API

Я тут на минуточку напомню, что FIG в PHP FIG - Framework Interop Group. И цель этой группы как раз делать интерфейсы, позволяющие делать совместимые компоненты, в частности, фреймворков. Чтобы можно было не писать, например, классы команд миграции доктрины отдельно для Yii, одельно для Symfony, Лары и тд, а написать один класс, который будет работать в любом из них, если ему через DI скормить правильные зависимости и правильно вызвать потом согласно спецификации стандарта.

На условный DI же есть стандарт. Да, есть куча разных имплементаций и конфигурируются они все по-разному. Но стандарт есть и вполне успешный как по мне. Почему не сделать такой же для консоли?

PHP Дайджест № 207 (29 июня – 12 июля 2021)

Мы точно один и тот же дайджест комментируем? Я вот про это

PHP Дайджест № 207 (29 июня – 12 июля 2021)

Ну вот в статье примерно это и написано да, что возможно сделают clone with. Это решит проблему, да.

PHP Дайджест № 207 (29 июня – 12 июля 2021)

Если вы при этом считаете, что работаете с мутабельным объектом — это ваши проблема.

Я считаю, что работаю с тем классом, который прописан в сигнатуре, не более. Какой там написан - так с ним и работаю.

PHP Дайджест № 207 (29 июня – 12 июля 2021)

Ну, так \DateTimeImmutable тоже крякает, как мутабельный объект.

Ну это не совсем правда. У него все это более явно прописано в сигнатурах мутирующих методов. А доступ к ним есть только в том случае, если вы явно знаете, что работаете с \DateTimeImmutable. Если у вас сигнатура \DateTimeInterface, а вы пытаетесь использовать это как \DateTime, а по факту там оказался \DateTimeImmutable - то вы ССЗБ. Если у вас сигнатура \DateTime - то, \DateTimeImmutable вы туда просто не передадите.

PHP Дайджест № 207 (29 июня – 12 июля 2021)

чтоб при изменении свойства создавался новый объект

Не очень понятно, как это должно выглядеть для пользователя программиста.

$immutable = new Immutable('data');
$immutable->data = 'new data';

В какой переменной у нас окажется новый объект с измененными данными при таком вызове? + Это очень неявное поведение, больше похоже на бомбу замедленного действя. Люди будут пытаться работать с этим как с мутабельным объектом (потому что он выглядит и крякает как мутабельный объект) и это неизбежно будет приводить к фрустрации, когда они будут понимать, что в итоге оно не работает как они предполагали.

Валидация в приложении на PHP (часть 1 — валидация доменного слоя)

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

Валидация в приложении на PHP (часть 1 — валидация доменного слоя)

а) какое-то голословное утверджение. а могут работать и корректно, отвечу я вам. как напишете

б) валидации, которые максимально не используют БД нагружают ее больше, чем те, которые на каждый запрос пытаются выполнить блокирующую запись, я правильно вас понял?

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

Валидация в приложении на PHP (часть 1 — валидация доменного слоя)

Ну вот здесь категорически не соглашусь. в апп валидации можно выполнять прямо на том DTO, что вы получаете при вызове API, на конкретных его полях. Отдавать ошибки на таких полях - 0 проблем, какое поле\объект валидировали - то в ошибке и указали. Когда дело доходит до сохранения в БД - это значит что у нас уже давно нет DTO, мы работаем с некоторой entity и валидацию выполняем на ней (пусть и в БД). И даже тут повезет и мы можем смапить обратно поля ентити на поля дто, то нам все равно нужно будет для каждого такого констрейнта индивидуально писать дополнительно обработчик ошибки в коде

Валидация в приложении на PHP (часть 1 — валидация доменного слоя)

Т.е. во всех таких случаях вам нужно включить в условие валидации еще и кода который с ней работает.Соответственно это решает вопросы и а/б тестирования и откатов релизов и т.п.

Звучит уже слишком сложно на уровне валидации констнейнтов в БД. это получается надо где-то на уровне сессии задавать "фиче тоглы", которые должны учитываться при работе констрейнта? Я не слишком скиловый БД разработчик, поэтому я сходу даже не скажу, заработает ли это на %databasename%. Не говоря уже о том, что это начинает походить на мем про буханку.

Валидация в приложении на PHP (часть 1 — валидация доменного слоя)

Ну и сразу задам следующий вопрос - насколько хорошо все это масштабируется. для валидации в приложении мне достаточно масштабировать приложение и дать ему реплику на чтение данных. Для валидации в БД, полагаю, мне надо сделать попытку блокирующего апдейта

Валидация в приложении на PHP (часть 1 — валидация доменного слоя)

Ну и конечно, шелуха проверок уровня апп пропадёт

На самом деле это был мой следующий вопрос, насколько удобно потом из БД эти ошибки выцарапывать, чтобы, скажем, скоммуницировать партнеру, который делает нам апи запрос (или того хуже, загружает файл), что вот, мол, ты нам загрузил неправильные данные вот в этом поле в этой строчке

Валидация в приложении на PHP (часть 1 — валидация доменного слоя)

О, если вы покажете такой констнейнт на БД, я бы посмотрел. Необходимость маркировки у нас задается для конкретных категорий товаров с конкретной даты. Категории товаров - это дерево, в котором есть наследование (т.е. если маркировка обязательна для промежуточного узла, то и для всех дочерних тоже). А еще обязательность маркировки зависит от страны, в которой мы торгуем.

Я не говорю что валидация не нужна. Я конкретно про констрейнты на БД.

Валидация в приложении на PHP (часть 1 — валидация доменного слоя)

обновления к нам прибежит клиент и спросит, а Вы же говорили что это реализовали, а оно не работает

Ну это неправда, оно уже релизнуто и может находится в этом же a\b тестиорвании месяц, и пока мы ждем этот месяц мы все равно не можем раскатать эту миграцию. Поэтому она все равно так или иначе будет раскатана руками. Да, может с доп удобствами вида now(), но это не сильно принципиально здесь уже (лично для меня из этого треда, не говорю что вообще не принципиально)

Мне гораздо интересен другая часть мессаджа, а именно зачем нам вообще нужен такой констрейнт. И я как раз доформулировал кейс. Представьте себе банальное a\b тестирование. Оно может вообще месяцами идти. И при этом у нас параллельно работают две версии. Одна - с емейлами, вторая без. Т.е. весь код должен успешно работать длительное время без этого констрейнта. Зачем мы его будем накладывать?

Валидация в приложении на PHP (часть 1 — валидация доменного слоя)

И не встречал проектов где над этим бы заморачивались, т.е. релизили сначала код который поддерживает и старую и новую версию схемы БД, потом накатывали миграции, потом накатывали версию приложения которая работает только с новой схемой. Проще было пожертвовать несколькими десятками секунд простоя и накатить всё одновременно. Ну и я не могу придумать кейс когда бы новое правило консистентности, выкаченное на десяток секунд раньше, ломало бы систему.

У нас почти так, только наоборот.

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

После завершения миграций катится собственно сам релиз. Т.к. миграция обратносовместимая, то роллинг релиз работает. Если с релизом проблема - откатывается чаще всего только код. Поэтому в нашем случае если будет выкачен миграцией констрнейнт, пусть и динамический, то при откате все сломается. Т.е. либо надо констрейнт катить отдельным релизом после, либо что-то еще вручную придумывать.

Проще было пожертвовать несколькими десятками секунд простоя и накатить всё одновременно. Ну и я не могу придумать кейс когда бы новое правило консистентности, выкаченное на десяток секунд раньше, ломало бы систему.

При поэтапном релизе (когда вы раскатываете новый релиз сначала на 10% инстансов например, потом на 50%, потом на 100%) несколько десятков секунд могут занимать пару часов наблюдения за раскаткой. И все это время у нас будут создаваться заказы и с емейлом и без. И все должно работать. Поэтому я не вижу большого смысла в констрейнте, который мы через несколько часов наложим.

Валидация в приложении на PHP (часть 1 — валидация доменного слоя)

Вам разве религия не позволяет подставлять дату динамически?

Религия доставляет мне сложность катить миграцию идеально в то же время, в которое происходит релиз кода, который запрещает так делать или обрабатывает такую ситуацию. Это если забыть про откаты релизов, например. Вплоть тдо того, что у вас может быть какой-нибудь роллинг релиз и два часа у вас половина пользователей создает заказы с емейлом, а половина без, так как у вас идет поэтапный деплой. с какого момента мне выставлять дату ограничения если там через один идут заказы с емейлом и без? такой констрейнт просто свалится, какую бы дату я не поставил (потому что все равно возможен откат релиза)

Транзакция на 2 системы с обеспечением ACID — практически не реализуемая инженерная задача.

C обеспечением ACID - да, безусловно. Но если вы пишите распределенные системы, есть вполне конкретные паттерны, например saga.

 я бы отправлял после всех БДшных чеков, и изменений БД, но до коммита транзакции в своей системе

А вот за такие вещи часто делают внушение уже нам. Т.к. это приводит к тому, что в БД появляются очень долгие транзакции, часто еще и с блокировками (что деградирует вашу систему). Мы так часто делаем, да (но не для валидации), т.к. это просто, но не очень правильно.

Да и вообще я сторонник того что все проверки надо делать в БД,

Я лично за то, чтобы в БД были только те констрейнты, которые бизнес готов высечь на бумаге (если мы говорим в терминах DDD). Т.е. если бизнес готов сказать, что с полуночи 07.07.2021 мы заказы без емейлов дропаем, даже те, которые в 23:59 еще оформлялись в старом интерфейсе где нет емейла - то и ладно.

Валидация в приложении на PHP (часть 1 — валидация доменного слоя)

— прямо в коде у нас зафиксирована дата изменения схемы данных

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

БД гарантирует что данные консистентны и удовлетворяют CHECK'у если миграция прошла

Ваша БД - возможно. А если у вас несколько систем? А если у вас несколько внешний интеграций? Какие констрейнты вы будете отдавать им на работу с этими сущностями?

Да и в целом, держать констрейнты в БД - это конечно максимально надежно, не спорю. Но это значит что вы в своей бизнес логике дошли до момента сохранения данных в БД с невалидными данными. Т.е. все что вы сделали до этого (а это могли быть и нетранзакционные операции, например запросы во внешние системы) - невалидно

Валидация в приложении на PHP (часть 1 — валидация доменного слоя)

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

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

Если говорит конкретно про ваш кейс, то представим, что у нас простенькая доставка суши и нам всегда хватало только телефона. а вчера пришел бизнес и сказал, что хочет обязательно еще и email. Сразу возникает вопрос - становятся ли все старые заказы невалидными? наверное нет. С ними можно продолжать работать. Сразу возникают проблемы с деплоем, т.к. появляются три этапа - добавляем необязательное невалидируемое поле, потом добавляем инпуты и только потом добавляем обязательную валидацию. Но поле в БД все равно останется нуллабельным и мы не можем гарантировать остальным получателям данных по заказам, что там заполнен email

Идеальный каталог, базовая библиотека

Скажем, пресловутый поиск по параметрам все равно отдается на откуп внешнему поисковому движку

Ну, это не всегда так. У меня есть опыт работы с системой, у которой быстрый поиск для клиентов - да, отдельный поисковик из производных значений (он не индексируют напрямую базу а отдельный поток данных из нее). а для внутренних нужд - на базе. Плюс есть задачи массовой обработки сущностей - это иногда удобно делать транзакционно, что тоже лучше работает, когда поиск идет по БД

Идеальный каталог, базовая библиотека

CREATE INDEX publisherhash ON books USING HASH ((data->'publisher'));

Это понятно, что так можно, но это кажется несколько расходится с той идеей, что пользователь(оператор) может сам атрибут создать (иначе зачем нам EAV, а не предописанная в коде схема). Создавать индексы по действиям пользователя - я не уверен что хорошая затея, особенно на нагруженной базе.

Если бы у EAV не было проблем с производительностью, то все бы на нем и сидели — никто не любит накатывать DDL в продакшене :)

Ну, это можно решать другим способом, например мастер данные хранить как EAV, а для производительных операций использовать отдельный слой, который будет работать с документами. Такое решение

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

Мы сами в новых задачах склоняемся к тому, чтобы делать документное хранилище как раз из-за того, что с ним гораздо комфортней работать при многих сценариях. А везде, где некомфортно - будут сделаны отдельные слои, которые решат эту проблему более эффективным способом, если необходимо

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность