Alexander
Зачем мне то об это ты пишешь, я только понять не могу.
Alexander
Нравится быть не как все - пожалуйста, кто ж тебе запрещает. Отстань только юродивый.
The Ant
так ты сам ворвался, даже не поняв о чем речь... хосспаде
Alexander
Речь о том, что очередной дурачок считает себя умнее всех и кладет на рекомендации сообщества, лучшие практики и т.д. Твой случай не уникален, будь спокоен. Но обычно это свидетельство одинокого фриланса, потому что в офисе опытные коллеги всегда дадут за такое по рукам.
Возможно я бы и прошел мимо, но прямо сейчас переписываю большой и старый проект за такими умниками, и у меня сильный огонь пониже спины.
The Ant
Ты щас лучшими практиками называешь пример Елисеева, который пишет в основном один и делает это в качестве обучающего материала? кек.
The Ant
я бы лучше послушал человека, который является архитектором в большом и сложном проекте с несколькими командами. Я б ему даже слова не сказал против.
А ты - нонейм какой-то, пришел тут и сходу в окна давай выкидывать.
The Ant
ах да, еще кочергой по голове, предварительно. Аргументируя это тем, что не бест практис. окау
Alexander
https://symfony.com/doc/current/best_practices.html#use-the-default-directory-structure
Лучшими практиками я называю лучшие практики.
Alexander
Я бы тоже с удовольствием послушал архитектора в большом и сложном проекте, желательно с большими нагрузками и несколькими командами. Но пока за 17 лет ни одного архитектора в пхп проектах не встречал.
Зато встречал людей, обсуждающих архитектуру проектов в отрыве от самих проектов.
Alexander
Дмитрий
А вообще я бы тоже хотел посмотреть на реальные проекты на симфони с бест практис, хайлоад, 1000 ентити, 300 контроллеров и 20 человек в команде, где бы такое найти?
Nikolay
Дмитрий
ведь можно же взять структуру, обезличить её, выложить на хабр под чужим аккаунтом )
Дмитрий
Или... во всех этих проектах в кодовой базе творится дичь и такое стыдно кому-то показывать )))
Nikolay
Дмитрий
спасибо, было бы классно
Andrey
вообще ещё дядюшка Боб писал, что надо абстрагироваться от фреймворков и все их best practices - только для того, чтобы ты дальше им пользовался
Правда, менять фрейм ты вряд ли будешь (разве что в самом начале), но если абстрагироваться, то апгрейд проще проходить будет
Maks
давайте еще помяним культовую статью с хабра)
Andrey
Это какую?
Maks
https://habr.com/ru/post/253297/
Дмитрий
Andrey
И они все недоговаривают 😂😂😂
Дмитрий
поговорить бы с ним по душам, вдруг выяснится что на практике он смело так кладет на все свои книжки и привязывается к фреймам ))
Дмитрий
а то вон DDD и SOLID все с ними носятся, а потом оказывается что это все хорошо работает только на проектах N+ сложности (масштабности) и эту самую N никто не знает ))
Юра
Ко всему надо подходить критически
Юра
Ничего не надо воспринимать буквально
Юра
Крайности плохо
Юра
Еще пару кепских фраз?
Юра
Дядя Боб такой же человек. Не сверх разум
Юра
Должна быть гибкость ума
Юра
А то будет как в поговорке, скажи дураку богу помолиться, он себе лоб разобьёт
The Ant
ведь можно же взять структуру, обезличить её, выложить на хабр под чужим аккаунтом )
https://www.youtube.com/watch?v=SycSx0Qp3eg&t=3910s
Привязка ко времени.
Секрета особого нет, есть проблема, что люди не хотят сесть и подумать хотябы 10 минут, о том, что они делают и почему. В тупую копируют "бест практис" или берут за эталон демку какую-то. А всё, что не вписывается в эту картину воспринимают в штыки.
Что касается книг. Мы ведь программисты, мы обязаны уметь создавать абстракции в голове, примерно моделировать всякие штуки умозрительно. И поэтому странно требовать от книг точных инструкций. Книги дают направление, куда подумать. К чему стремится.
Дмитрий
дак программисты ленивые же, все хотят серебряную пулю, чтобы кто-то за них придумал вау, а они скопипастят )
Дмитрий
ну и страх что твой велосипед окажется гуано )
Shokha
Добрый день!
Как-то можно использовать условию в .yaml файле?!
App\Service\Geocoder\GeoCoderInterface: '@App\Service\Geocoder\YandexGeocoder'
у меня есть такая строка в services.yaml я хочу от зависимости что написано в .env класс поменялся на гугл или опенстрить и.т.д
Александр
Александр
ADMIN_EMAIL из .env
Shokha
Такое тоже пойдет! но я так попробовал тоест я путь написал в .env
@App\Service\Geocoder\YandexGeocoder
потом указал его в services.yaml он ругнул
Shokha
думаю надо использовать services.php а не services.yaml
Иван
Dmitry
Так тут не 50 их https://github.com/ElisDN/demo-project-manager/tree/master/manager/src/Controller
Там не то, что вам кажется.
У Елисеева в проектах модель приложения с командами, сущностями и сервисами разделена на папки-модули.
А уже UI слой контроллеров с представлениями и моделью чтения расположен как шлюз поверх модулей.
В UI обычно нужно компоновать данные из разных модулей, поэтому если нужен общий контроллер вывода постов с комментариями и автором из разных модулей, то в какой-то один модуль его поместить не получится. Только сверху над всеми модулями.
К тому же, наличие отдельного от модулей UI-слоя даёт возможность менять/сливать/делить модули не ломая внешний интерфейс.
В итоге в проекте удобно делать модульную структуру для доменной модели, а над ней размещать монолитный HTTP-шлюз с версионированием для UI. В тех же микросервисах аналогично делают общий API Gateway, который ходит в независимые микросервисы и склеивает их данные.
A
Раз уж такая пьянка, вопрос в тему: а как разложить Read модель? Прям все должно быть поверх модулей? Иногда (в концепции CQRS) запросы на получение какого-то агрегата или сущности содержат крайне нетривиальную логику, которую, если хочется добиться переносимостей модулей между проектами, заманчиво положить к модулю. Допустимо?)
Dmitry
Раз уж такая пьянка, вопрос в тему: а как разложить Read модель? Прям все должно быть поверх модулей? Иногда (в концепции CQRS) запросы на получение какого-то агрегата или сущности содержат крайне нетривиальную логику, которую, если хочется добиться переносимостей модулей между проектами, заманчиво положить к модулю. Допустимо?)
Обычно свои фрагменты можно поместить в каждый модуль и потом из общего шлюза делать три запроса в три модуля. Например, из блога получаем отсортированные посты, потом из модуля профиля запрашиваем имя автора по post.author_id и из модуля комментариев запрашиваем сами комментарии по post.id
Но если для отчётов нужна сложная выборка со сложной сортировкой и фильтрацией, которую по частям так не запросишь и не склеишь, то тогда либо костылить запрос с JOIN-ами в таблицы разных модулей, что нарушает изоляцию, либо делать отдельный модуль или микросервис для такого отчёта и туда по событиям складывать в нужном виде копию фильтруемых данных из других модулей.
A
Обычно свои фрагменты можно поместить в каждый модуль и потом из общего шлюза делать три запроса в три модуля. Например, из блога получаем отсортированные посты, потом из модуля профиля запрашиваем имя автора по post.author_id и из модуля комментариев запрашиваем сами комментарии по post.id
Но если для отчётов нужна сложная выборка со сложной сортировкой и фильтрацией, которую по частям так не запросишь и не склеишь, то тогда либо костылить запрос с JOIN-ами в таблицы разных модулей, что нарушает изоляцию, либо делать отдельный модуль или микросервис для такого отчёта и туда по событиям складывать в нужном виде копию фильтруемых данных из других модулей.
Т.е. все Query фрагменты должны быть разложены именно по модулям? Часто даже не в рамках отчетов требуются джоины между таблицами разных модулей. Например, хотим список постов, сортированный по дате последнего комментария.
В своих проектах, поэтому, есть некоторые Query "поверх" модулей, а некоторые - внутри. И это слегка смущает команду.
Юра
Назови его ReportModule
Юра
И джоини на здоровье
Dmitry
A
Дмитрий
Дмитрий
Дмитрий
https://www.youtube.com/watch?v=eU4ajVB9Lz4
The Ant
The Ant
The Ant
Размазано ровным слоем по приложухе. Кмк удобнее все сгруппировать все в одном месте
Дмитрий
мне кажется ты все равно не понял смысл
смотри еще раз картинку https://t.me/symfony_ru/41978
контроллеры находятся выше модуля SignUp потому что их 5 штук
вот в чем смысл такого разделения, сегодня ты думаешь что у тебя один контроллер только из фронта приходит запрос для этого модуля, а завтра тебе вдруг понадобилось сделать внешнее api и будешь в модуле создавать новые контроллеры? тем самым размазывая ровным слоем эти контроллеры и потом гляда на каталог src хрен пойми где лежат контроллеры касающиеся внешнего апи
The Ant
The Ant
Конкретно сайнап, регистрация, подтверждение, выдача токенов для апи и т.д. можно куда нить в "акканут" положить. Вместе с секурити аутентификаторами.
Дмитрий
в общем, мая считает что так делать можно, НО необходимо написать документацию и соглашения: что? куда? где? как?
чтобы новый программист пришел на проект и мог прочитать эти соглашения, а не рыться в коде проклиная автора
или... просто юзать уже готовое соглашение симфони ))
The Ant
Ну мелкие приложухи делаю как дефолт аппку симфы. Где пара функций. И то уже хочется эту мелочь на голенг переписать 🤣
Andrey
Контроллеры будут лежать там, к чему они относятся
Сильно не читал, видео не смотрел, но так понял речь про то, что приложение выступает фасадом для модулей. То есть контроллеры к модулям отношения не имеют
Типа той же гексагональной архитектуры: чтобы из одной части в другую что-то передать ты адаптеры юзаешь, а внутри оно все независимо
Выше как раз писал про независимость от фреймворка. Вот у тебя зависимость внутрь модуля прокидывается. Даже не зависимость от фрейма, а зависимость от приложения. В другом приложении уже не сможешь это задействовать
Если убрать зависимость, то и получим схему с картинки, а в другом приложении тебе просто надо будет новый адаптер (в простейшем случае, контроллер) запилить и все работать будет
The Ant
Да, но смысл тогда брать фреймворк если ты от него полностью абстрагируешся?
Andrey
Ну не полностью, бл в основном
А смысл хотя бы в том, что потом мажорные версии повышать проще, у тебя ж мало точек соприкосновения будет
+ ладно если давно разрабатываешь, а если только начал, то можно быстро на другой фрейм переключиться
На старой работе как-то yii решили использовать, потому что куча разработчиков на нем работу искал. Там, правда, с нуля делали, но могли на зенде начать, а потом о yii подумать и быстро бы все заменили
The Ant
Пересаживаясь на другой фрейм в любом случае с нуля начнёшь писать. И быстро это не получится. Юзая Лару будешь привязан к магии Лары. В уии будешь без контейнера, на сервис локаторе. В симфе тоже в основном свои приколы типа дохтрины
Andrey
Ну это если best practices следовать, а если им просто как инструментом пользоваться и по возможности независимо, то потом и заменять все проще
Ну это в теории, а в жизни без должного опыта ещё больше проблем огребешь
The Ant
А сейчас вообще мода пилить свои монолиты на голенг микросеовисы
The Ant
В симфе левые инструменты сложно юзать. Например сайкл вместо доктрины вкорячить тот ещё квест. Аналогов всяким аргумент резолверам просто нет. Единственное что получится писать действительно независимое это всякие сервисы, которые дтошки принимают на вход и плюются ими же на выходе.
Andrey
кстати, недавно про семвер писали
на работе php7.2, симфони 3.4
решили повышать постепенно, сначала php до 7.4 поднять
обновил версию php до 7.4, в composer указал используемую версию как 7.4.5 (потому что один из пакетов конфликтовал с 7.4.0 и версия пакета в итоге не росла, а уменьшалась), запустил composer update и словил ошибку
> PHP Fatal error: Could not check compatibility between Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\LazyLoadingValueHolderGenerator::generate(ReflectionClass $originalClass, Zend\Code\Generator\ClassGenerator $classGenerator) and ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator::generate(ReflectionClass $originalClass, Laminas\Code\Generator\ClassGenerator $classGenerator), because class Zend\Code\Generator\ClassGenerator is not available in .../vendor/symfony/symfony/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/LazyLoadingValueHolderGenerator.php on line 25
полез разбираться и...
если все правильно понял, то в симфони не всегда сидят умные люди и вот почему...
где-то внутри сорцов (того самого LazyLoadingValueHolderGenerator) есть отсылка к Zend\Code\Generator\ClassGenerator из пакета laminas/laminas-code: 3.5, только прямой зависимости в композере нет, а зависимость есть от ocramius/proxy-manager, в котором как раз и указана зависимость от пакета laminas/laminas-code: 3.5
и вот ocramius/proxy-manager повысил мажорную версию laminas/laminas-code, а у себя повысил только миноруню версию (публичное API же не поменялось)
а в мажорной версии laminas/laminas-code класса Zend\Code\Generator\ClassGenerator уже нет, зато есть класс Laminas\Code\Generator\ClassGenerator
потому и падает
т.е. в принципе легко можно на обратную несовместимость наткнуться
Andrey
The Ant
кстати, недавно про семвер писали
на работе php7.2, симфони 3.4
решили повышать постепенно, сначала php до 7.4 поднять
обновил версию php до 7.4, в composer указал используемую версию как 7.4.5 (потому что один из пакетов конфликтовал с 7.4.0 и версия пакета в итоге не росла, а уменьшалась), запустил composer update и словил ошибку
> PHP Fatal error: Could not check compatibility between Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\LazyLoadingValueHolderGenerator::generate(ReflectionClass $originalClass, Zend\Code\Generator\ClassGenerator $classGenerator) and ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator::generate(ReflectionClass $originalClass, Laminas\Code\Generator\ClassGenerator $classGenerator), because class Zend\Code\Generator\ClassGenerator is not available in .../vendor/symfony/symfony/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/LazyLoadingValueHolderGenerator.php on line 25
полез разбираться и...
если все правильно понял, то в симфони не всегда сидят умные люди и вот почему...
где-то внутри сорцов (того самого LazyLoadingValueHolderGenerator) есть отсылка к Zend\Code\Generator\ClassGenerator из пакета laminas/laminas-code: 3.5, только прямой зависимости в композере нет, а зависимость есть от ocramius/proxy-manager, в котором как раз и указана зависимость от пакета laminas/laminas-code: 3.5
и вот ocramius/proxy-manager повысил мажорную версию laminas/laminas-code, а у себя повысил только миноруню версию (публичное API же не поменялось)
а в мажорной версии laminas/laminas-code класса Zend\Code\Generator\ClassGenerator уже нет, зато есть класс Laminas\Code\Generator\ClassGenerator
потому и падает
т.е. в принципе легко можно на обратную несовместимость наткнуться
Надо было сначала симфу апнуть до 4ки 😄
Andrey
А вчера узнал, что проект есть вообще на первой симфони 😈
The Ant
Прост во избежание эксцессов всяких юзать те версии пыхи, что были во времена релизов конкретных версий. Тройка помойму была вообще на 5.4 , не?
Andrey
с 5.6 мы уже апнулись, но до 7.2 потому как часть кода на 7.2 уже работала (спасибо докеру)
The Ant
Вчера хотел сразу на 6 апнуть, минуя 5.4, но куча пакетов ещё не перенесено. По этому пришлось на 5.4 обновится
Дмитрий
The Ant
Вы рзможно сложнее будет переехать, т.к. накопится много изменений
Дмитрий
зато это можно будет делать сильно реже, а то посмотри на план развития, тебе почти не дают времени на переход к новому минору как старый уже умирает
The Ant
Ну я с пятерки начал активно симфу юзать. Не было прям сверхсложных моментов при обновлении. В основном рецепты обновить да так по мелочи на пару часов.