Ответы пользователя по тегу Symfony
  • Кто должен настраивать CORS nginx или php-framework?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    С точки зрения производительности эффективнее это настроить на стороне nginx, с точки зрения производительности труда - как мидлвэр к вашему приложению (то есть на уровне фреймворка, либо на уровне PSR-7)
    Ответ написан
    Комментировать
  • Symfony 2 или Laravel для распределённой системы?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    без разницы, в принципе. И на том и на том можно сделать как просто и быстро так и плохо. Разница по сути только в подходах по работе с базой (доктрина - domain centric, ларавелевская ORM - database centric).

    Ну и да, в Laravel вполне себе удобный IoC (даже не смотря на то что в symfony2.8 уже сделали автовайринг), и концепция мидлвэров. Но у Symfony2.8 можно включить микроядро, и по производительности он уйдет вперед (чисто фреймворк, без учета ORM и т.д.)
    Ответ написан
    5 комментариев
  • Веб приложение на Symfony Components, как правильно?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Разделить приложение по паттерну MVC,


    Ваш MVC плавно превращается в MVA, а MVA плавно превращается в луковую архитектуру.

    и слоя такого как модель нет

    Потому что модель это не слой, это объект. Один одинешенек (в контексте одного реквеста) такой... его задача взять запрос и выплюнуть данные. То есть для контроллера модель это сервис, для шаблона модель это... сущности или DTO.

    Модель это ВСЕ ЧТО УГОДНО что умеет обрабатывать данные и содержит их.

    Symfony же это UI фреймворк, который всего-лишь позволяет вам быстро организовать UI к вашему приложению (HTTP API или CLI скрипты это только UI приложения) и потому как именно вы будете организовывать архитектуру приложения - это чисто ваша забота. Симфони вам предоставляет только контейнер зависимостей что бы организовать сервисный слой удобненько.

    MVC это бесполезные три буквы которые не говорят ровным счетом ничего о том как у вас чего организуется. MVA уже лучше и это именно то что использует подавляющее большиинство на бэкэнде последние лет 10 (в том числе и RoR), но концепция та же - разделение логики представления данных от логики обработки этих данных.

    Тогда как поступить с этим? Есть компонент форм для валидации данных и заполнения полей авторизации-регистрации, есть ORM а как мне связать и валидацию и записи через ORM в объект User допустим.


    Вам как правильно сделать или как удобно? Как удобно зависит от вас. Вы можете и писать из форм прямо в сущности анемичные и т.д. и еще как хотите. Но по сути флоу должен быть примерно таким:

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

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

    Так же рекомендую почитать вот эту штуку: The Twelve Factors
    Ответ написан
    Комментировать
  • Как рядовому веб-разработчику можно использовать в повседневной жизни Amazon EC2?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    вся мощь амазона заключается в возможности скейлиться. То есть никакой магии, мы можем по API трекать нагрузки и по API добавлять сервера когда надо. Автоматически. Или там у вас планируется новогодняя акция и поток пользователей будет в 10 раз больше - добавили сервачков на месяц. Так же у AWS миллион сервисов, которые сойдут для начала (например если надо быстро запилить транскод видео - без проблем. Нормально на EC2 уже можно сделать когда по стоимости будет сильно дорого (или вообще взять ноду с GPU).

    А просто так - AWS слишком дорогой, проще взять на диджитал океан дроплетов и не париться. Возможности "скейлиться" у них больше.
    Ответ написан
    3 комментария
  • Как лучше построить модуль Транзакции в symfony?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    0) Никаких TransactionBundle. Вы эту логику не сможете реюзать, а значит нет смысла делать бандл. Почитайте symfony best practice. У вас должен быть один AppBundle и все, больше ничего. Вы можете пытаться выносить какие-то части инфраструктуры, которая не привязана к бизнес логике в отдельные бандлы для последующего реюза, но бизнес логику приложения реюзать не выйдет.

    1) почитайте про event sourcing. Этот способ хранения данных идеален для платежных транзакций, собственно в банках и т.д. этот подход и используют десятилетиями, да даже та же база данных хранит лог транзакций.

    2) уберите flush их сервиса и вынесите его в контроллер. flush коммитит транзакцию в базу, и нам надо это делать когда мы завершили работу с оными а не "где-то посередине".

    3) оборачивать это добро в еще одну транзакцию глупо, потому что... доктрина и так сделает транзакцию. В любом случае по хорошему это надо делать в декораторе.

    4) call_user_func_array в вашем случае - пример плохого решения.

    5) по умолчанию persist использовать нужно только для тех сущностей, которые мы только что создали (в нашем случае - транзакция), либо тех которые мы явно вынули из unit of work (а у нас нет вызова $em->detach).

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

    7) сервисы менеджеры - отстой. Называйте сервисы нормально.

    8) вместо кучи сервисов можно ввести разные объекты транзакций. Например FundTransaction, IncomTransaction и т.д. У вас же в сервисах почти весь код дублируется. А так можно было бы всю логику с этими операциями сложить прямо в сущности.

    9) НИКАКИХ DIE! даже для дебага.

    public function transactionAction(Request $request)
    {
        $data = $request->request;
        $transactionDTO = new TransactionDTO(
             // вообще я бы тут просто ID пользователя возвращал... но я упорот по изоляции приложения от UI
             $this->get('security.token_storage')->getToken()->getUser(), 
             $data->get('sender_account_type'),
             $data->get('recipient_account_type'),
             $data->get('amount')
        );
        // с исключениями разберется фронт контроллер
        $this->get('app.transaction_processor')->process($transactionDTO);
        // вот теперь сохраняем изменения
        $this->get('doctrine.orm.entity_manager')->flush();
    
        return new Response(null, 201); // создали новую запись в журнале транзакций
    }


    class TransactionProcessor
    {
          private $transactionsRepository;      
    
          public function __construct(TransactionRepository $repository)
          {
               $this->transactionsRepository = $repository;
          }
    
          public function process(TransactionDTO $dto)
          {
                // create это статический метод фабрика у абстрактного класса Transaction
                // читать шаблон проектирования "абстрактная фабрика".
                $transaction = Transaction::create($dto->getSender(), $dto->getRecipient(), $dto->getAmount());
                
                $this->transactionsRepository->add($transaction);
          }
    }


    дальше мне по логике не понятно, почему у вас одна транзакция на двух человек, полюбому у sender-а будет один тип транзакции а у ресивера другой. Можно запомнить кому мы чего передавали и только.
    Ответ написан
    7 комментариев
  • Как верно организовать сервисную архитектуру Symfony2 для поддержки нескольких версий API одновременно?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Вопрос остается только в том, как в PHP , а в частности, в Symfony организовать такую структуру ?


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

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

    Если говорить о архитектуре - идеальный вариант это гексагональная архитектура. Тогда мы будем воспринимать разные версии API просто как разные адаптеры к слою приложения.
    Ответ написан
    2 комментария
  • Symfony 2. Как красиво организовать конфигурацию бандлов в базе данных?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    да, сделайте сервис аля ParamsProvider или что-то в этом духе. И все. Либо инджектите его либо через выражения подставляйте.
    Ответ написан
    5 комментариев
  • Как вывести только entity_id в JMSSerializer вместо всей сущности?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    или же я неверно настроил сериализатор?

    Именно так. Хотя я на 100% не уверен что вы организовали ресурс правильно (коль у вас там связи есть).

    В целом решить вашу проблемы при сериализации поможет inline опция. К сожалению в обратную сторону оно не работает (что поделать, jms serializer не мэйнтейнится активно уже пару лет).

    Альтернатива - для объекта вашего типа просто можно объявить свой хэндлер для сериализации/десериализации.
    Ответ написан
  • Как обойти дублирование кода в контроллере Symfony2?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Были мысли вынести все в обычный менеджер, но не думаю, что бросание HTTPException-ов менеджером хорошая идея.


    Да, потому есть такая штука у FosRestBundle как ErrorController который умеет конвертить обычные исключения в корректный респонс со своими статус кодами.

    Вынести все эти штуки в ваш сервис-менеджер, что бы вся бизнес логика была рядом, это здравая мысль.
    Ответ написан
  • Symfony2 права доступа к функционалу сайта. Какие механизмы использовать?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    ну вот там где выводите и решайте. И где проверяете... Где удобно там и можно. В симфони есть встроенные проверки аля isGranted
    Ответ написан
    Комментировать
  • Как писать кошерные юнит тесты в symfony2 когда вся логика в контроллерах?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    юнит тесты - это тесты которые тестируют юниты (то есть подразумевается хоть какая-то степень изоляции, от полной (когда все замокано) до не очень полной (если мокать все не сильно удобно)).

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

    По вашим пунктам - делайте так, как вам удобно. Ну то есть суть всего сводится к тому что бы с кодом вашего приложения было удобно работать. Тесты это способ упрощения внесения изменений в код. Если вам из-за тестов не удобно - надо придумать как сделать так что бы было удобно (либо у вас что-то не так с тестами либо с кодом, раз его не удобно тестить).
    Ответ написан
    2 комментария
  • Вопрос по дополнительной нагрузке на сервер?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Как вы поступаете?

    Я пишу нагрузочные тесты.

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

    p.s. А где twig? у него все эти задачи уже давно решены (вроде проверки является ли элемент первым) и причем весьма эффективно.
    Ответ написан
  • Как решить вопрос с получением текста причины отказа в доступе при использовании CustomVoter и IsGranted()?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Счет заблокирован

    это бизнес правило, его не надо в секьюрити воутер пихать.

    Не хватает средств на счете

    Опять же это правило не в секьюрити воуетере должно быть. Тут вы можете просто бросить исключение или еще чего в соответствующем сервисе.

    Секьрити воутеры нужны только для определения может ли пользователь выполнять какое либо действие или нет. И причина тут только одна может быть - нет прав.

    Другие бизнес правила и ограничения будьте добры реализовать в сервисах своих. Можете тот же chain-of-responsibilitites шаблон использовать если вам так угодно, но...
    Ответ написан
  • Правильно ли я понял работу фреймворков?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Фреймворки это набор готовых решений для стандартных задач. Воспринимайте их как кучу отдельных библиотек. Скажем нет смысла раз от раза писать снова и снова маршрутизацию запросов и т.д.

    В контроллере использую готовые функции например работа с БД.

    Основная задача контроллера - быть посредником между представлением данных (HTTP например, или web интерфейс, или CLI) и логикой их обработки. То есть работать с базой данных в контроллере вы можете, но не рекомендуется (только если вы знаете к чему может это привести и чем плохи толстые контроллеры).

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

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

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

    Тоесть половина функционала это функции фреймворка, половина это мои велики...

    Не велики, а бизнес логика. Фреймворк предоставляет вам каркас, решение типичных задач. В случае простого CRUD соотношение вашего кода к коду фреймворка библиотек может быть 1/10. В случае сложной бизнес логики и специфичной инфраструктуры - 10/1.
    Ответ написан
    Комментировать
  • В каких случаях удобно использовать поле EntityID вместо дополнительных таблиц?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    вам нужно наследование (table inheritance) и разные типы объектов для разных типов нотификаций. Это если брать "обычно".

    p.s. при работе с доктриной проще оперировать сущностями и взаимоотношением оных а не таблицами. Это domain-centric штука, а не data-centric.
    Ответ написан
  • Symfony меняет даты взятые из таблицы. Как получать не отформатированые данные?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    что значит "меняет"? Она конвертит строки в DateTime, дальше вы сами уже форматируйте как вам хочется.
    Ответ написан
    Комментировать
  • Как правильнее реализовать получение данных со стороннего API?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    я опущу свою тираду по поводу бандлов в рамках одного приложения (должен быть только один бандл - AppBundle, остальное нужно только для реюзабельных вещей. Если вы не можете реюзать ваше решение то нет смысла запирать это в бандле), сосредоточусь на контроллерах.

    Как вы написали, контроллеры должны обрабатывать HTTP запросы, вот пусть они этим и занимаются. Берут запрос, забирают и обрабатывают данные, просят сервисы что-то сделать (а не делают сами) и потом выплевывают результат работы этих сервисов наружу.

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

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

    А еще было бы неплохо попрактиковать TDD но это если вам позволяет время. Вообще настоятельно рекомендую перейти на практику TDD (почитайте Кента Бэка на эту тему).

    И еще говорят, что считается правка composer библиотеки напрямую изменяя код в vendor не хорошим, как дополнять либы новым функционалом?


    Все что в vendor должно оставаться неприкосновенным. Если вы хотите расширить функциональность вы должны обернуть чужую штуку в свою, или реализовать интерфейсы предоставленные чужой штукой... ну короч расширять можно путем декорирования и... в случае с плохими библиотеками - наследованием. Ну и еще вариант - пул реквесты но это только если вы уверены что эта функциональность нужна не только вам.
    Ответ написан
    Комментировать
  • Как правильно создать модель в symfony с именем 'transaction'?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    переименуйте сущность и все будет хорошо. Таблицы желательно называть во множественном числе (transactions). И вообще лучше избегать использования зарезервированных слов в названиях таблиц или полей таблиц.
    Ответ написан
  • Использование DataTransformer в Symfony2?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    валится на преобразовании значения из объекта в строку, смотрите что у вас хранится в качестве значения startPlan
    Ответ написан