Stanislav
Написал такой запрос
Konstantin
еще раз: пишите код текстом, не скринами
Konstantin
вдруг я захочу сейчас вам поправить кусок кода, я его перепечатать с экрана должен?
Stanislav
Да сейчас напишу
Konstantin
уважайте собеседников/коллег
Stanislav
уважайте собеседников/коллег
Просто думал он тут коряво будет
Konstantin
для этого есть форматирование
Konstantin
protected function configure(): void { $this ->setName('demo:test') ->setDescription('Some dirty stuff here') ; }
Konstantin
например вот, отлично читается
Stanislav
например вот, отлично читается
Это прям из редактора скинули пример?
Stanislav
Смотрите вот это вот в репозитории $dql = 'SELECT p FROM APP\Entity\Post p WHERE p.photos IS NOT EMPTY'; $qb = $this->getEntityManager()->createQuery($dql); return $qb->getResult(); Вот это в контроллере
Stanislav
Похоже я как-то не так скинул код
Konstantin
Написал такой запрос
так вот, тут джойна не хватает. select p, ph from App\Entity\Posts p JOIN p.photos ph where p.photos is not empty
Stanislav
Понял, спасибо, сейчас попробую
Konstantin
Это прям из редактора скинули пример?
выделяете код, на маке жмете cmd + shift + k
Konstantin
как на винде - не знаю, но поищите
Stanislav
У меня mint, поищу
Stanislav
так вот, тут джойна не хватает. select p, ph from App\Entity\Posts p JOIN p.photos ph where p.photos is not empty
Спасибо, все работает и вместо кучи запросов, один запрос
Konstantin
таки почитайте доку 🙂
The Ant
В таком варианте можно указать часть аргументов и привязать к переменным некоторые? например я хочу убрать газл клиент дефолтный и логгер, но они идут первыми. Значит нада остальные просто привязать к переменным и всё. (только для этого класса). В варианте с ямлом вроде легко делается. А тут чет...
Vlad
‘$param’ => service(‘ant’)
Anton
доброго дня , подскажите пожалуйста относительно реализации: допустим есть сервис Foo которому в констроктур приходит BarInterface есть сервисы Bar1, Bar2 которые реализуют интерфейс BarInterface. и в зависимости от параметра http реквеста инжектятся в Foo
Иван
Фактори сервис
да, но нет потому что фактори будет явно зависеть от реквеста где-то в недрах
Иван
а всё, что касается реквеста, должно происходить рядом с контроллером
Юра
Хз откуда такие умозаключения
Сергей
Делаешь BarProvider. В него добавляешь свои сервисы. И в методе getService() получаешь нужный сервис. У каждого сервиса есть метод - supports. В supports проверяешь условия для выбора этого сервиса. Инжектишь этого провайдера в нужное место и там уже из него получаешь нужный сервис
Сергей
в симфе можно список сервисов в провайдера добавить в services.yaml через теги
Иван
Юра
Сервис фабрика, который зависит от RequestStack, и выдаёт нужный тип сервиса в зависимости от параметра, по-моему все явно
Юра
А от реквеста зависят не только контроллеры
Юра
Например тот же profiler который собирает данные риквеста
Иван
Например тот же profiler который собирает данные риквеста
с профайлером никакого сравнения, он вообще старается всё слушать а вот почему придёт тот, а не иной сервис в зависимости от аргумента реквеста - это может оказаться нежданчиком для нового человека
Konstantin
доброго дня , подскажите пожалуйста относительно реализации: допустим есть сервис Foo которому в констроктур приходит BarInterface есть сервисы Bar1, Bar2 которые реализуют интерфейс BarInterface. и в зависимости от параметра http реквеста инжектятся в Foo
так делать не нужно, это flaky-сервис. поведение дерева зависимостей должно быть максимально детерминированным то что ниже советуют с сервис-локатором - тоже антипаттерн. должно быть два сервиса, либо один декорирующий, внутри которого есть иф, выбирающий поведение
Konstantin
если, допустим, нужно будет воспроизвести этот функционал в консольной команде, тесте или где-то еще, это доставит очень много боли, тк внутренний (сервисный) слой знает о внешнем (слой доступа - хттп)
Konstantin
это протечка абстракции, лучше ее избегать
Konstantin
лично я предпочитаю сделать массив handlers в сервисе-контейнере, у каждого из хендлеров есть метод supports. в цикле перебираете все хендлеры, скормив на вход ваш хттп-реквест, какой хендлер принял этот запрос - такой и обработал
Konstantin
и контейнер чистый от лишних завимостей от хттп, и srp удоволетворен, и гибкости море
Konstantin
если нужен пример кода, чуть позже могу накидать иллюстрацию этого подхода
Konstantin
это не про доку, а про clean code, скорее. но ваще это и внутри симфони активно используется (см. метод supports в коде компонентов)
Konstantin
Я то же самое предложил)
да я жопой читаю)
Сергей
да я жопой читаю)
Главное не писать жопой)
Иван
Главное не писать жопой)
жопой только Билл Гейтс умеет программировать
Konstantin
Главное не писать жопой)
я так без работы останусь
Vite4eg
Всем привет. Мне надо сформировать сложный Excel. Выдали пример файла. Там куча всяких данных, и есть блок со списком товаров. Создавать Excel я умею. А есть какие-нибудь подходы по шаблонизации этого? Взять например готовый Excel, разметить отдельные ячейки как место для подстановок. Делал кто? есть пример как это реализовать по красоте?
Konstantin
<?php // controller public function fooAction(BarService $barService, Request $request): Response { return new JsonResponse($barService->handle($response)) } class BarService { /** @param FooHandlerInterface[] */ public function __construct(private readonly array $handlers) { } public function handle(Request $request): array { foreach ($this->handlers as $handler) { if ($handler->supports($request)) { return $handler->handle($request); } } } } interface FooHandlerInterface { public function supports(Request $request): bool; public function handle(Request $request): array; } class FooHandlerImpl1 implements FooHandlerInterface { public function supports(Request $request): bool { return $request->query->has('foobar'); } public function handle(Request $request): array { return [ 'foo' => 'bar', ]; } }
Konstantin
добавить по вкусу проверок-исключений-логики
Dmitriy
Так http реквест же у вас протек в сервис FooHandlerImpl1
Konstantin
так ради бога, передавайте не реквест, а ParameterBag
Dmitriy
уж лучше dto
Konstantin
или вообще массив. это как раз нормально, тут реквест - это просто контейнер данных. плохо когда сервис зависит от текущего реквеста в текущем контексте
Konstantin
уж лучше dto
нет разницы, вы в этом хендлере можете проверять что угодно - куки, заголовки, урл-параметры, тело запроса. даже если это и описать всё в дто, получится примерная копия Request, это как раз не особо умно
Konstantin
с реквестом из httpfoundation одна проблема - не совсем удобно в тестах мокать, но и то большой проблемой не является
Konstantin
ну вы читаете той же жопой, которой и я, похоже. я русским языком, раза два, написал "зависимость сервиса от хттп". это значит, что проинициализировать сервис в контейнере в зависимости от состояния хттп-запроса - это ересь
Konstantin
это никак не связано с тем, что в сервисе у меня будет use Symfony\Component\HttpFoundation\Request
Konstantin
это не та зависимость, речь именно о service arguments, я не знаю как еще понятнее это объяснить
Dmitriy
как пишете так и читаем )
Konstantin
ну вот нет уж)
Юра
Может можно сразу в фабрику передать нужный параметр? Вроде же можно выражения инжектить
Юра
Тогда не надо зависеть от риквеста, только от строки
Юра
Konstantin
а значение запроса откуда взять? expr lang-ом вытащить из @request_stack.mainRequest.query.get('foo')?
Konstantin
это как раз антипаттерн - состояние контейнера недетерминированно, грубо говоря, у нас каждый запрос свой контейнер
Юра
Контейнер один, тоо который скомпилироался
Konstantin
нет
Konstantin
если он зависит от параметра запроса, ты не можешь сказать в данный конкретный момент, во что отрезолвится сервис @foo
Юра
А зачем это тебе
Konstantin
мне? мне - незачем, исходный вопрос был как сделать так, чтобы "если в запросе foo == bar, то достать один сервис, иначе - другой"
Иван
вопрос, что это за роуты такие, что на одном роуте разные хендлеры
Иван
может это разные роуты?
Konstantin
да всякое бывает. у меня вот, например, есть проект. где несколько разных заказов - разные таблицы на разные группы товаров
Юра
Или например когда тебе надо в зависимости от домена подсунуть БД
Юра
Да полно примеров