Хорошая практика в Symfony 2 (по личному опыту)

Доброго времени суток, уважаемые хабравчане. Сегодня увидел статью на хабре «Официальный гайд по лучшим практикам в Symfony» и понял, что мне есть что исправить добавить. К вашему вниманию список личных советов и объяснение к ним.

Используйте по меньше аннотаций


Лично я люблю аннотации, но с опытом понял, что они приносят некий дискомфорт. Дело в том, что всю конфигурацию перенести в аннотации нельзя. Остается 2 варианта:

  • Максимум в файлах конфигурации ( например yml);
  • Немножко в файлы, немножко в аннотации.


Если выбрать второй вариант, то при росте проекта получается каша. И в вашем коде аннотаций больше, чем логики. Отговорки по типу «так легче находить роуты» не принимаются. Так как если расскидывать файлы конфигураций правильно, ты всегда знаешь, где находятся роуты к определённым контроллерам. Я уже молчу про команды в консоли, по типу route:debug, и отладчик, в котором видно название екшена и имя роута.

Плохой пример (как по мне):



Менеджеры и репозитории выносить в отдельные папки


Сразу приведу плохой пример, как устроено на текущем проекте:



Все классы менеджеров должны быть в папке Manager, классы репозиториев Repository. Если этого не делать, то при появлении уже 5-10 сущностей со своими менеджерами и репозиториями жить становится «веселее».


В шаблонах всегда определяйте блоки с яваскриптом и стилями


Всё просто. В каждой отдельной странице вы сможете переопределять и подгружаться будут всегда только те яваскрипты и стили, которые нужны. Так же советую в самом базовом шаблоне эти блоки оставить пустыми. А в бандлах при создании главного layout.html.twig их заполнять.

Конфигурации бандлов хранить в AppBundle/Resources


Даже если проект небольшой, изначально привыкайте хранить конфигурации бандлов в AppBundle/Resources/, а не в app/config. В app/ только ссылки. В основном это касается роутинга и сервисов.

Entity описывать в файле конфигурации


Сущности лучше описывать в конфигурации, например, в AppBundle/Resources/config/doctrine/Entity.orm.yml, и генерить с помощью команды doctrine:generate:entities, которая сама сгенерирует классы сущностей. Когда конфиги сущностей находятся в файлах, сами классы выглядят чище. Так же вы будете уверенны, что в них нет ошибок.

Для тестов создавайте отдельную базу


В файле parameters.test укажите параметры тестовой базы, в которую загружаете фикстуры. Так вы всегда будете уверенны, что тестируете одни и те же данные. Возможно, все так и делает, просто на текущем проекте я столкнулся с отсутствием такой практики.

Конечно это всё банальные вещи, но есть люди, которые так не делают и из-за этого страдают мученики программисты, которые пишут после них.

Буду рад если кто-то напишет свои советы в комментариях.

Добавленно:

  • Регистрировать форм типы в DI, а не создавать через new (Иначе не работают form type extensions) — to0n1
  • Использовать lazy прокси для зависимостей в twig extension (Иначе строится полное дерево зависимостей на каждый request) — to0n1
  • По возможности не использовать трейты совместно с кофигами в аннотациях (нет возможности перекрыть аннотации в классе использующем трейт) — to0n1

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 30

    +3
    Как уже обсуждалось в предыдущем топике, использование аннотаций очень спорный вопрос. С каждым новым разработчиком (со своими взглядами) любой проект рискует превратиться в кашу. Например, новый разработчик взглянет на ваш код и подумает: что за ламер делал проект, даже не знает, что в симфони можно использовать аннотации :)
    В идеале конечно к каждому проекту должен прилагаться style guide с обоснованием того или иного решения.
      0
      Да, это спорный.
      0
      Чем не угодили аннотации? Конечно, это дело вкуса, но даже на скриншоте-примере все выглядит вполне понятно (не знаю зачем три роута на один экшн, ну да ладно). Все читабельно и ясно с первого взгляда.

      Про менеджеры и репозитории полностью согласен, там с этим столкнулся, теперь всегда все в отдельных папках. Даже родительские классы для сущностей (если таковые имеются) стараюсь хранить в отдельной папке, т.к. получается удобнее.
      То же и к следующим двум пунктам про блоки js/css и конфигурацию бандлов. Очень удобно.

      Entity опять же — дело вкуса. У меня все в аннотациях, например на проекте с около 50-ю сущностями в десятке бандлов (сами судите много ли мало ли), и все удобно.

      P.S. Исключительно мое мнение
        0
        По поводу аннотаций, действительно вопрос спорный. Я думаю здесь есть грань, которую каждый определяет сам для себя.

        По поводу сущности. Генерить с файлов конечно не объязательно, но вносить изменение в файл yml одно удовольствие. Выглядит всё очень читабельно и аккуратно, когда сущность в нём описана. Не мешают аннотации, реализации методов и т.д.
        image
          +1
          Тут скорее лень играет. Мне вот действительно лень открывать два файла и вносить изменения в два файла при добавлении нового поля.
          При этом используя аннотации я не теряю ни в производительности (все кешируется), ни в функционале (можно описывать и поля и валидацию и создание форм).

          В общем, предлагаю оставить аннотации в покое, это дело вкуса ))
            +1
            Не нужно вносить изменения в 2 места)
            Вносим изменения в файл конфигурации и команда doctrine:generate:entities всё делает за Вас (добавляет свойство в класс, добавляет геттеры и сеттеры). Так что так получается даже быстрее )
              0
              Но эта команда не добавляет нужные мне методы ))
              Довольно часто в моделях есть свои методы для каких-либо нужд. На то они и модели.

              Я все равно пользуюсь doctrine:generate:entities для генерации геттеров/сеттеров (т.к. генерируются add/remove методы для коллекций). И, кстати, она не добавляет has~/is~ методы, что довольно неудобно, а они зачастую нужны.

              В итоге получается, что yml файл становится просто «еще одним файлом который нужно редактировать». По крайней мере для меня ))
                0
                Да, есть свою нюансы) Ну понятно что он не будет создавать реализацию callback'ов например. На то он и файл конфигурации. В нём описаны какие методы на каких стадиях срабатывают, а в модели описываем реализацию. Опять таки, просто читабельней немного)

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

                Удобней? Да) Читабельней? Ну конечно)
                image

                  0
                  Согласен на счет описания каллбеков :)
                  Правда, ни разу не пользовался ими в таком виде. Обычно все вынесено в отдельные класы listener/subscriber, т.к. требуются другие сервисы, которые в сущности не вклинишь (по хорошему).
                    0
                    Ну нужно понимать когда использовать колбеки, а когда listener/subscriber.

                    В любом случае спасибо за дискуссию)
                      0
                      > Ну нужно понимать когда использовать колбеки, а когда listener/subscriber.
                      Само собой.

                      > В любом случае спасибо за дискуссию)
                      Не за что )
          0
          Несколько роутов это нормально, например, полный и короткий урл.
          Но проблема аннотаций тех же роутов это приоритет при их загрузке, т.е. чтобы роут из одного контроллера был выше роута из другого контроллера, и тут уже всё зависит от имён файлов контроллеров. Вроде периодически всплывают PR с решением, но что-то никак не смерджат: последний из них завис в начале сентября, но Фабьен хоть метку повесил — уже хорошо :)
        • UFO just landed and posted this here
            +2
            >> Для тестов создавайте отдельную базу

            Более обобщенно, создавайте свой environment
              +1
              Думаю что Ваш список можно дополнять до бесконечности…

              От себя могу добавить:
              • Регистрировать форм типы в DI, а не создавать через new (Иначе не работают form type extensions)
              • Использовать lazy прокси для зависимостей в twig extension (Иначе строится полное дерево зависимостей на каждый request)
              • По возможности не использовать трейты совместно с кофигами в аннотациях (нет возможности перекрыть аннотации в классе использующем трейт)
              0
              По поводу аннотаций — уберите @param и @return, сразу станет чище. По поводу контроллера — зачем вы проверяете $entity? Симфони самостоятельно кинет исключение, если не найдет сущность.
              По поводу репозиториев — полностью поддерживаю.
              По поводу моделек, я считаю у вас не правильный подход с генерацией. Все что нужно phpstorm сгенрирует вам сам, а вот контролировать схему и класс модельки одновременно, а не в двух файлах — очень удобно. Ну и есть классная идея — сначала пишешь классы, а потом делаешь их них Entity. Тогда код будет чище.
                0
                Это не я писал. Это скриншот кода, который писали до меня.
                  0
                  При подходе с файлом конфигурации, я дискомфорта не ощущаю. А вот читабельность и чистота, для очень важна. Хотя это настолько субьективно, что даже спорить нет смысла.
                    +1
                    Мне тоже очень нравится Entity-oriented подход + Аннотации. Имя переменной одновременно отвечает за название поля для класса и таблицы.
                    С PhpStorm можно создавать поля и на лету генерить и рефакторить getters/setters, не думая о ссылках на них в коде.
                    0
                    На счет аннотаций совсем не согласен. Когда ты видишь сразу какие «дополнительные возможности» привязаны на это свойство класса — это хорошо. А когда у тебя разбросано по 5 файлам конфигурации (а я работал с таким проектом пол года назад) — то это ужасно. Приходится сначала находить все файлы конфигураций (там же не только Entity, там и timestampable и другие) и изучать их. Да и разработчики симфони не зря сделали это по умолчанию.

                    По поводу поиска нужного метода для роута — это дело секунд с любым вариантом конфигурации (phpStorm + symfony2 plugin).
                    На счет репозиториев и менеджеров. Менеджеры действительно лучше хранить в директории Manager, а вот репозитории отделять от Entity смысла особо не вижу. Все равно я обычно не смотрю на дерево файлов, оно у меня вообще скрыто. Лучше пользоваться своей памятью и быстрым поиском файла — нахожу за пару секунд нужный (там очень хороший алгоритм выбора файла, когда ты знаешь, что ищешь), в то время как другие ищут его зачем то в списке файлов глазами. Но это видимо придет со временем к некоторым, а к некоторым — никогда.

                    На счет конфигурации бандлов!
                    Описание сервисов бандла должно быть в самом бандле. Если потребуется выносить бандл, как отдельный вендор для другого проекта (а в хорошей практике это частое событие), описания этих сервисов придется «вернуть» в бандл. И основные роутинги тоже нужно описать в самом бандле. А вот префикс может быть добавлен в самом текущем приложении, то есть в app. Но смысла выносить это в ресурсы опять же не вижу никакого, т.к. app — это и так настройки текущего приложения. А когда они все лежат в config директории — это очень удобно. Но согласен, что их лучше разделять на несколько конфигов.

                    В разделе «добавлено» со всем согласен (формы, lazy twig, трейты).

                    Немного не согласен с «всегда определяйте блоки». Symfony2 — это система в которой можно переопределить практически все что хочешь. И заранее определять блоки (особенно если не выносится это в вендор) смысла не вижу. Когда потребуется, всегда можно взять в нужном шаблоне что-то в блок и переопределить этот блок в другом.
                      0
                      Ну аннотации — тема заезженная и субъективная. Лично мне нравится когда всё структурировано. Хотя аннотации в нужной мере, этому не мешают.
                      Про роуты, бандлы согласен, это я и писал.

                      Блоки. Опять таки, не критично. Вообще всё что в статье написано — не критично.
                        0
                        Всё таки добавлю про сущности. Логика не должна переплетаться со структурой базы. Скажем так, пусть переплетается, но должно быть место, в котором описана только структура. Для этого и существует конфигурационный файл для Entity. В котором нет реализации методов и логики. А чистая и прозрачная структура. Это приходит со временем и особо полезно при разработке enterprise-проектов. Опять таки, без этого работать можно, и даже привыкнуть. На практике, только при использовании такого подхода, понимаешь все его прелести. Конечно я не беру в учёт ситуации, в которых сущность состоит из 5 полей, и нет дополнительных методов, кроме как геттеры и сеттеры.
                          0
                          Интересная особенность построения симфони, что entity не должно содержать логики и используется в основном для описания сущности в базе. Так что выделять описание сущности в базе из описания сущности в базе…

                          Я работал на одном большом проекте, где все было в yml. Сейчас работаю на другом огромном проекте, где много используется аннотаций. И мне с аннотациями намного удобнее. Единственный плюс на yml был, что сторм научился дополнять описание entity в yml. Чего нет в аннотациях пока что.
                            0
                            Вы меня не поняли. Логика должна быть описана в класса Entity. Всё верно. Но, я говорю про место, в котором описуеться только структура, без реализации. Ну чтоб напрмиер увидеть структуру таблички в базе, мне не нужно знать какие там данные. Аналогично. Мне нравится описание сущностей в yml, так как там ничего нет лишнего. Выше я прикреплял скриншот, в котором видно о чём я. Опять таки. Это субьективно.
                              +1
                              Единственный плюс на yml был, что сторм научился дополнять описание entity в yml. Чего нет в аннотациях пока что.


                              Использую Symfony2 Plugin + PHP Annotations дополнение работает на ура!
                                0
                                Спасибо! Поставил PHP Annotations — классная штука. Теперь я вспомнил, что когда-то ставил ради интереса и пользовался, пока версию сторма не сменил и забыл про этот плагин.
                          0
                          Может попросить добавить вопрос про аннотации в Symfony Codestyle Guide, который буквально недавно вышел?

                          Only users with full accounts can post comments. Log in, please.