saber1in
На скринах есть все, там 3 скрина
saber1in
На последней ссылке
Юра
Все норм вроде
saber1in
Я вот тоже не понимаю
saber1in
Недавно начал изучать Symfony компоненты, может что-то не так сделал
saber1in
Может ему нужна конфигурация во время создания, я в di сделал просто createValidator
saber1in
На втором скрине
Юра
А у тебя не симфони
saber1in
Нет, просто использую компоненты
Юра
В симфе из коробки а так нужно смотреть возможно нужно зарегать драйвер для чтения атрибутов
saber1in
Я вот не могу найти создание самого класса, в доках просто в параметрах контроллера приходит
Vlad
там метод enableAnnotationReader или чет такое
Михаил
Ну во первых NotNull у тебя не сработает так как поле не nullish - у тебя при попытке записать в мейл null произойдёт исключение от симфы и код упадёт с 500
Vlad
если получаешь валидатор через фабрику без дополнительных метамаркеров, передавай констрейнты вторым аргументом
Vlad
там метод enableAnnotationReader или чет такое
скорее всего теперь это метод enableAttributeReader или около того
Михаил
Во вторых нет никакого смысла валидировать объект на который ты намапил данные - нужно валидировать данные, щас скину пример
saber1in
Но она не отрабатывает, можете пожалуйста доку скинуть для начальной конфигурации если вам не трудно
Михаил
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Validation; $validator = Validation::createValidator(); $input = [ 'name' => [ 'first_name' => 'Fabien', 'last_name' => 'Potencier', ], 'email' => 'test@email.tld', 'simple' => 'hello', 'eye_color' => 3, 'file' => null, 'password' => 'test', 'tags' => [ [ 'slug' => 'symfony_doc', 'label' => 'symfony doc', ], ], ]; $groups = new Assert\GroupSequence(['Default', 'custom']); $constraint = new Assert\Collection([ // the keys correspond to the keys in the input array 'name' => new Assert\Collection([ 'first_name' => new Assert\Length(['min' => 101]), 'last_name' => new Assert\Length(['min' => 1]), ]), 'email' => new Assert\Email(), 'simple' => new Assert\Length(['min' => 102]), 'eye_color' => new Assert\Choice([3, 4]), 'file' => new Assert\File(), 'password' => new Assert\Length(['min' => 60]), 'tags' => new Assert\Optional([ new Assert\Type('array'), new Assert\Count(['min' => 1]), new Assert\All([ new Assert\Collection([ 'slug' => [ new Assert\NotBlank(), new Assert\Type(['type' => 'string']), ], 'label' => [ new Assert\NotBlank(), ], ]), new CustomUniqueTagValidator(['groups' => 'custom']), ]), ]), ]); $violations = $validator->validate($input, $constraint, $groups);
Михаил
https://symfony.com/doc/current/validation/raw_values.html
Михаил
вот так тебе не нужны будут никакие метадата ридеры и прочая шелуха и валидатор будет работать как guard
Михаил
потом уже провалидированные данные можешь гарантированно мапить на сущность
saber1in
Да я могу передать просто поле и вторым параметром ассерты, но я хотел через аннотации
Михаил
Прости что не отвечаю на твой вопрос, просто это лучшая практика
Vlad
Понял, тогда лучше так
Validation::createValidatorBuilder()->enableAttributeMapping()
Михаил
Твоя сущность может вернуть объект констрейнтов, но это какой-то yii получается ))
saber1in
А как вы делаете через аннотации или через параметр функции?
saber1in
Нашел ответ на stack overflow
saber1in
Теперь работает
saber1in
Validation::createValidatorBuilder()->enableAttributeMapping()
Спасибо по твоему ответу начал искать
Михаил
Нашел ответ на stack overflow
Чем ты такие красивые скрины делаешь?
saber1in
CodeSnap расширение в VsCode
saber1in
Выделяешь нажимаешь правую кнопку мыши и снизу будет CodeSnap
Михаил
@hidelocker а что за фреймворк такой интересный. Реквест и респонс как параметры - это какой-то микрофреймворк?
saber1in
SlimPHP
saber1in
Интересный легкий, быстро можно наклепать
Михаил
Круто
Михаил
Вот у тебя есть $body['email'] = null; Есть поле в сущности class User { public string $email = ""; } ты ДО валидации данных записываешь $user = new User(); $user->email = $body['email']; и тут же словишь исключение о том, что "попытка записать null в string" Поэтому NotNull не спасёт А было бы class User { public ?string $email = ""; } тогда бы сработало. Но делать поле nullish когда оно не должно быть null - это нарушение инварианта. Точнее прямой путь выстрелить себе в ногу
saber1in
А как тогда валидировать через компоненту, в доках вроде надо сначала заполнить объект и потом уже передать в валидатор
Михаил
Использовать dto
Михаил
или валидировать чистые данные как описано здесь https://symfony.com/doc/current/validation/raw_values.html
saber1in
Понял, сейчас почитаю
Юра
Ну лучше да валитировать дто
Юра
Ну вот пусть @hidelocker проверит но вроде там не 500
saber1in
Там не 500
saber1in
Просто ошибка от самого валидатора
saber1in
Сработало ошибка по длине из аннотации
Михаил
Блин такое ощущение что мы на разных языках пишем. У меня при присваивании null исключение, у вас - валидатор срабатывает
saber1in
Перевод с доки: Валидатор будет использовать значение nullесли типизированное свойство не инициализировано. Это может привести к неожиданному поведению, если свойство содержит значение при инициализации. Чтобы избежать этого, убедитесь, что все свойства инициализированы перед их проверкой.
saber1in
Может в этом дело
Юра
https://github.com/symfony/validator/blob/7.0/Mapping/PropertyMetadata.php#L46
Юра
Как видно не должно быть 500 по идее а должно быть нул с точки зрения валидатора
Юра
Но выстрел в ногу возможен легко. Забыл добавить NotNull, валидатор пропустит это и потом первый геттер вызовет 500
Юра
У меня как-то на автомате если поле может быть нул то сразу инициализировать его нулом. Заодно идее подсветит если тип не нулабл. Не знаю правильно так делать или нет но я так делаю )
Михаил
Ладно ребят. Опять вы не понимаете.
Павел
По-моему валидатор хендлит это и там не будет 500
До валидатор это просто не дойдет. Михаил говорит о том, что в типизированное своество нельзя пропихнуть не его тип. Например если string $name но в него null не записать, упадет пыха
Павел
Это в кейсе, когда в дто или сущность ручками проставляется реквест. Это был его пример. $user = new User(); $user->email = $body['email']; Вы же наверное рассматриваете когда реквест десериализируется на дто/сущность и потом валидируется. Да, там валидатор не провалидирует непроинициализированные свойства но и не упадет по 500
Юра
А если там сериализатор свойство запихивает?
Павел
А если там сериализатор свойство запихивает?
Он запихивает только то что ему передано. Т.е. если свойсво отсуствует в запросе, то оно и не будет десериализоваться. Но если будет null, то скорее всего должно упасть по ошибке денормализации.
Михаил
До валидатор это просто не дойдет. Михаил говорит о том, что в типизированное своество нельзя пропихнуть не его тип. Например если string $name но в него null не записать, упадет пыха
боже спасибо, спасибо! Мне иногда кажется что на мне весит проклятье. Я говорю "Солнце встаёт на востоке, а садится на западе", но люди вокруг говорят "Нет, ты говоришь о том, что солнце встаёт на западе, садится на востоке"
Михаил
тут дело ещё не в этом. Вот вы делаете внешний апи. У вас есть те, кто интегрируется в ваш апи. И допустим у них происходит какая-то ошибка и ИНОГДА вместо строки с DateTime они отсылают объект (кто пытался сериализовать DateTime могли сталкиваться) Так вот, если вы сначала пытаетесь намапить данные на объект - то вы вместо строки получите массив и упадёте с 500. Не знаю как вы, но при получении 500 от внешней апи я просто ухожу в ретрай и никак не применяю другую логику обработки. А вот если бы вы сначала провалидировали данные, то отправили бы или 422 или 400, что для потребителей вашего апи является красным флагом, когда они ловят это в рантайме.
Юра
Если у проперти стоит дефолт велью (в контексте серилазитора), то сериализатор поставит это дефолт велью. Короче суть в том что не факт что там будет 500 ошибка о чем говорил Михаил
The Ant
Напомните, доктриновский репозиторий умеет же по числовому идентификатору находить связь one2one? типа: $entity = $this->videoRepository->findOneBy(['file' => (int) $fileId]); Обычно туда объект подставляется. Проверять долго ) м.б. кто на память в курсе...
The Ant
у меня нету (
Vlad
Чего нету? Впн?
The Ant
чата гпт, регать лень, а фришные кастраты западло
Kirill
Спроси chat gpt
и он ответит хуйню)
Михаил
ну или свой у себя на компе раскатай
Kirill
Когда как)))
так и я могу
Kirill
там выбор из двух вариантов, или нет, или да