Yii: лучшие практики

В статье будут освещены следующие проблемы разработки и поддержки проектов на базе php-фреймворка Yii:

  1. Главные достоинства и недостатки
  2. Тестирование
  3. Нюансы использования ActiveRecord
  4. Сервис-ориентированный подход
  5. Новшества языка
  6. Расширение фреймворка




Yii я использовал в четырёх коммерческих проектах разной степени сложности. Это были, следующие решения:

  1. Проект с нагрузкой порядка сотен тысяч хитов в сутки, с таргетингом, аналитикой по миллионам событий, обработкой мультимедиа и т. п. Рекламный сервис. Основные технологии:
    1. Yii1
    2. MySQL
    3. RabbitMQ
    4. Memcached

  2. Веб-интерфейс для одного из решений по управлению кампаниями на базе готового API аналитического сервиса. По сути простой web-GUI с некоторым кэшированием и минимальной серверной логикой. Основные технологии:
    1. Yii1
    2. SQLite
    3. bootstrap
    4. jQuery

  3. REST API на Yii2 для веб-приложения на AngularJS, и мобильных клиентов Android, iOS. Скидочная тематика, вся логика на сервере. Основные технологии:
    1. Yii2
    2. MySQL
    3. RabbitMQ

  4. Внутренняя система документооборота, узкоспециализированная под конкретную отрасль, но со множеством различных бизнес-процессов разных департаментов. Основные технологии:
    1. Yii1
    2. MySQL
    3. Клиентская часть была переписана на AngularJS 1 и отвязана от php.



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

Последний из перечисленных выше проектов (№4), разрабатывался около двух лет, к началу моего участия в нём. Ещё на собеседовании, когда я узнал о двухлетней разработке, без релиза, об использовании первой версии фреймворка (в начале 2015 года), я подумал что без проблем там не обойдётся. Но я согласился участвовать, чтобы принять challenge — взяться за то, что принято называть «унаследованный код». Да, тот самый, что вызывает самые разнообразные отрицательные чувства — отвращение, ненависть, отчаяние, страх — и следуя советам Фаулера, вооружившись тестами, сделать из долгостроя качественный, поддерживаемый, рабочий продукт. Год рефакторинга, смена архитектуры за несколько месяцев перед релизом и сам выход в продакшен проекта с подобной историей, заслуживают отдельной статьи — я получил бесценный опыт, которым хотел бы поделиться, если на то будет воля сообщества.

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


Yii о двух концах



Yii хорош низким порогом вхождения и тем, что способствует быстрому прототипированию. Эти же качества и являются источниками проблем.

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

Быстрое прототипирование, может создавать у заказчика и менеджмента иллюзию, что проект уже почти готов и можно начинать его эксплуатацию, а добавление функционала в будущем будет обходиться так же дёшево, как и на этапе прототипа. Такое развитие событий крайне невыгодно для разработчиков и чревато неоценимыми рисками для менеджмента и проекта в целом. Я склонен считать, что прототип должен выкидываться — это есть суть прототипа.


Тестирование



Модульное тестирование в сообществе Yii-разработчиков не распространено повсеместно. Есть обзор тестирования в официальной документации (1, 2), многие из расширений создаваемых энтузиастами покрыты тестами. Но, оттого что в сообществе большой процент разработчиков с малым опытом, которые ещё не доросли до автоматического тестирования, начинать проект на Yii по TDD в целом, скорее не принято.

Дополнительную сложность для юнит-тестирования может представлять использование шаблона Active Record. Об этом я подробнее напишу ниже.

В упомянутом проекте проводилось только ручное приёмочное тестирование. Были не поддерживаемые тесты под Selenium, почему-то написанные на Java, но они выполнялись слишком долго, а запускались слишком сложно, и, как следствие редко, результат давали неоднозначный.

Одно из первых мероприятий, предпринятых мной было подключение PHPUnit и применение TDD при разработке новых фичей и рефекторинге существующего кода, обучение других членов команды методикам автоматического тестирования.

Позже был использован Codeception для приёмочного тестирования API. Позже был использован Codeception для приёмочного тестирования API. Были попытки использовать его и для функционального тестирования веб-интерфейса, но на фронтенде, начавшем к тому моменту активно использовать AngularJS были проблемы с поддержкой таких тестов, пришлось временно отказаться.

О себе я могу сказать — test infected. Чего и Вам желаю. Я не могу разрабатывать без тестов. Я не верю в работоспособность чьего-либо кода, если на него нет тестов. Я верю что любой код, на который нет авто-тестов будет отправлен на помойку. Он просто будет ломаться со временем и в какой-то момент окажется, что дешевле его переписать с нуля и с тестами, чем приводить в работоспособное состояние, путём отладки вручную.

В Yii есть механизм для работы с фикстурами, который во многом компенсирует сложности тестирования Active Record. Поддержка Ваших фикстур — то о чём стоит задуматься с самого начала. Используйте для их организации способы, которые облегчат будущую поддержку:

  • можно использовать require для разбиения больших файлов по бизнес-процессам, ролям, ещё какой-то доменной логике
  • семантически осмысленные имена (aliases), указывающие в каких именно test cases эта запись используется, с какими другими моделями она связана (relation)
  • для меня было несколько неочевидных моментов в работе FixtureManager, пришлось читать исходники. Всегда стоит знать используемый инструмент
  • не забывайте явно очищать таблицы (tearDown / setUp), заполняемые в процессе теста, чтобы избежать побочных эффектов от разделяемого тестами состояния



Active Record



Active Record — это тоже один из плюсов и одновременно минусов фреймворка. Плюс в том, что при прототипировании database first подход, поощряемый кодогенерацией классов моделей по схеме, может существенно ускорить разработку, а также в том, что порой проще работать с моделью, в контексте которой можно делать и запросы и валидацию и вообще всё что с ней связано. Минусы начинаются, когда бизнес-логика слишком велика для того чтобы всю её помещать в модель, и нарушение принципа единственной ответственности даёт о себе знать — Active Record это же и Domain Model, и Repository, и Data Mapper, и Table и Row Gateways одновременно.

Если Вы видите, что предметная область сложнее сайта-визитки или банального блога — используйте альтернативные шаблоны проектирования, чтобы разгрузить ваши модели: в Yii есть разнообразные пути для этого:

  • можно использовать модели форм для валидации пользовательских данных, до того как передавать их в модель
  • валидаторы удобно оформлять отдельными классами
  • существуют поведения (bеhaviors для композиции вместо наследования!), которые помогают в организации различной переиспользуемой служебной функциональности
  • модель легко декомпозировать делегируя некоторые методы стратегиям — например, если вы кастомизируете во многих моделях метод search() — он наверняка становиться достаточно большим чтобы заслуживать подобный рефакторинг.


Такой подход проще в тестировании и позволяет моделям не заплыть «жиром».

Вообще предпочитайте композицию наследованию — старайтесь выносить функциональность из иерархии наследования в делегаты с узко-специализированным интерфейсом.

«Жирные» модели, один из самых распространенных антипаттернов, которые я видел в проектах на Yii. Я предпочитаю следующие подходы при работе с ActiveRecord:

  • всегда создавайте свой супер-класс уровня для моделей
  • не редактируете генерируемый код — наследуйте от его!
  • кастомизируйте шаблон и логику генератора для своих нужд — Yii позволяет делать это!
  • размещайте в ваших моделях только тот код, который находиться на уровне взаимодействия с базой данных — таблицы, имена колонок, условия запросов. Избегайте знания о структуре базы данных в других слоях приложения, хорошо если ваши классы Active Record будут самым низкоуровневыми в приложении
  • проверяйте результат работы gii: не все виды сложных связей генерируются корректно, иногда приходиться отступать от чистого реляционного проектирования или реализовывать вручную код, которые не удаётся сгенерировать.



Service Locator, services and singletons



По сути, экземпляр приложения, статически доступный как Yii::app() — есть сам себе singleton и сервис-локатор для компонентов приложения. Если без ООП фанатизма, это вполне рабочее решение, если вам не нужно иметь два разных экземпляра приложения в одном процессе.

Не скупитесь создавать сервисы — маленькие сервисы с минимальной ответственностью хорошо в тестировании, они предсказуемы и понятны. Для решения любой бизнес задачи удобно создать специализированный сервис, которые будет решать ровно одну эту задачу. Я предпочитаю в качестве компонентов приложения регистрировать фабрики таких сервисов — это позволяет наделять сервисы состоянием при необходимости. Так же фабрика даёт дополнительную гибкость при инициализации объектов, в сравнении с наиболее распространённым, судя по примерам в сети, подходом напрямую регистрировать сервисы с предопределённым состоянием в конфигурации приложения.

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

Для автокомплита ваших компонентов воспользуйтесь рецептом от Александра Макарова.


Namespaces и другие новшества языка



Так как первая версия Yii была выпущена в конце 2008 года и поддерживает php 5.1 — в ней не используются пространства имён на уровне ядра. Но это не мешает Вам использовать их. В проектах на первой версии я успешно использовал их.

Вместо использования т. н. Aliases Вы можете использовать статические имена классов — загрузчик их подхватит. То есть, конфигурация может выглядеть следующим образом (на примере модуля из официальной документации):

// «старый» подход
    'modules'=>array(
        'testmodule' => array(
            'class' => 'application.modules.testmodule.TestModuleModule',
        ),
    ),
// рекомендуемый в документации подход, для версий PHP >= 5.3
    'modules'=>array(
        'testmodule' => array(
            'class' => '\mynamespace\modules\testmodule\TestModuleModule',
        ),
    ),
// в 5.5 и выше это можно делать ещё удобнее
    'modules' => [
        'testmodule' => [
            'class' => \mynamespace\modules\testmodule\TestModuleModule::class,
        ],
    ],


И ещё пара улучшение для Вашего кода, о которых Вы возможно не знали, или забыли:

  • CgridView columns может принимать для value выражения не только в виде строки для eval'а но и анонимную функции.
  • Кастомизировав шаблон генератора можно использовать свои пространства имён, короткий синтаксис массивов, актуальное psr форматирование кода и всё что вашей душе угодно.
  • Yii1 можно подключить через composer.



Расширяйте фреймворк



Одним из недостающих классов в Yii1 для меня был web\Response, при том что существует Request. Написание простейшей реализации класса ответа, и добавление супер-класса для контроллеров, с обработкой оного в afterAction(), позволило модульно тестировать контроллеры, и в итоге избавить из от лишнего «жира».

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

А ещё, у сообщества есть полезные расширения, не только функциональные, но архитектурные. К примеру мы в проекте используем ObjectWatcher — реализация Identity Map — для того чтобы в разных контекстах работать иметь одни и те же экземпляры моделей, и NestedTransaction.

Не забывайте мудрые слова Стива МакКоннелла:

Программируйте с использованием языка, а не на языке.


Эта сентенция справедлива и для фреймворков: будьте Разработчиками, а не %framework_name%-программистами!
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 76

    +1
    Хочу заметить что
    Быстрое прототипирование, может создавать у заказчика и менеджмента иллюзию

    это не проблема конкретного фреймворка, также как и низкий порог вхождения.
      +2
      Да, не только конкретно Yii.
      Но, на мой вкус, в сравнении с другими решениями, часто используемыми в стеке для аналогичных задач (Symfony, Zend) он лучше именно для быстрого прототипирования и легче для новичков.
        0
        У меня тут нарисовалось несколько legacy проектов на Yii, которые поддерживают подрядчики, а я… ну вероятно курирую их. Так вот, у меня создалось впечатление, что некоторые особенности Yii поощряют использование «слабых» сторон PHP, ну и вообще непопулярных практик.

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

        Повсеместное использование god object и его публичных статических полей типа \Yii::$app->{whatever}, и, как следствие на вопрос, а «где DI» — глаза как у Кота из Шрека — «нет, не видели...»

        Собственно отсюда и низкий порог вхождения. И соответствующее качество на выходе.
          0
          >PHP шаблоны, которые буквально подначивают, чтобы в них всунули что-то не свойственное для представлений.

          Это каким таким образом?

          Такое можно везде наделать при желании :)
            0
            Ну в Twig надо приложить смекалку, чтобы такое провернуть =)
              –3
              Я вообще против дополнительных шаблонизаторов.
              PHP сам отличный шаблонизатор.

              С твигом не работал, но видел извращения в смарти, а иногда без них никуда. :)
                +1
                Не могу поддержать данную точку зрения (особенно в свете высказываний в стиле «не работал, но осуждаю»). Но если вас всё устраивает — пользуйтесь. Я не навязываю свою позицию.
                  +3
                  С твигом не работал, но видел извращения в смарти, а иногда без них никуда. :)


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

                  А извращения никогда не нужны. Если они нужны — значит вы где-то свернули нетуда. Хороший код должен быть скучным и предсказуемым.

                  p.s. Смарти ужасная штука… лет так 10 назад было прикольно, сейчас не очень.
                    0
                    >Новичкам нужна смирительная рубашка, и «снимать ограничения» нужно только по мере получения опыта и понимания того с чем работаешь.

                    Новичкам не стоит сразу лезть на фреймворки…
                    Целевая аудитория фреймворков — не новички ж? :)
                      +1
                      Новичкам не стоит сразу лезть на фреймворки…


                      Разумеется, но и в коммерческую или серьезную разработку им тем более не стоит лезть. Новички первый годик должны другие вещи изучать.

                      Проблему как раз таки представляют разработчики, которые пару месяцев потыкали PHP, взяли какой laravel и пошли «грабить караваны» на фриланс биржах. В итоге потом во всяких gitter-сообществах лавина тупых вопросов, которые решаются прочтением документации к фреймворку или к PHP (не говоря о базовых вещах вроде алгоритмизации или работе с базами данных).

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

                      Целевая аудитория фреймворков — не новички ж? :)


                      Фреймворки нужны для того что бы более эффективно подходить к разработке. Разработчик может инвестировать пару месяцев своего времени что бы разобраться во фреймворке, и это окупится за несколько проектов. Или же разработчик получит возможность влиться в команду более опытных чуваков на уже активно пилящийся проект и т.д. Словом вопрос трудозатрат и т.д.

                      А вот думать что фреймворки нужны просто так потому что без них не круто — это вредно, и да, такие люди тоже есть. Людей много, крайности разные бывают.
                      +1
                      Однако же какой кайф был, когда я первый раз котлеты (разметку) отделил от мух (логики). Да, смарти был тяжёл. Но это для меня тогда был первый качественный шажок вперёд к грамотной организации кода, к созданию приложений, поддерживать и развивать которые, уже не было одной сплошной болью ))
                        0
                        я потому и сказал что лет 10 назад было прикольно (ну или сколько там, лет 6-7 назад еже даже)
            +1
            Были не поддерживаемые тесты под Selenium, почему-то написанные на Java

            Потому что раньше не было нормального драйвера под PHP. То, что было фейлило слишком часто.

              0
              Сохранилось ещё такое предание, что писались они студентом-стажёром, которого занять чем-то надо было, а кроме Java он не владел ничем =)

              Как я предполагаю, год написания упомянутых тестов, вероятнее всего 2014.
              Я codeception уже использовал вместе с силениумом, примерно в это время, если ничего не путаю, не помню чтобы были большие проблемы. Но там не было потенциальных сложностей для тестирования, так что может просто повезло.

                0
                Селениум изначально Java-фреймворк. Лет 10 назад, когда вставал вопрос на чем писать тесты к API на Java мы проголосовали за Java, чтобы не париться с конвертациями. Но порог входа там конечно повыше чем в Yii, хотя традиционно (ошибочно) считается что тестировщик (в идеальном мире — инженер по качеству) должен быть не умнее программиста-джуниора.
                  +3

                  Не, ну в 2014 всё было уже нормально. Я про 2007—2009 где-то.

                –6
                Столкнулись на большом продукте с адовыми тормозами ActiveRecord и непрозрачностью DefaultScope'ов. Действительно, эти подходы годятся только для совсем маленьких сайтов.
                  +1
                  А можно подробнее про тормоза ActiveRecord?
                    –2
                    Вангую что тормоза не в самом ActiveRecord, а в чудовищном SQL-коде, который производят сложные relations в моделях Yii при неправильном их использовании.

                    Но это не Yii виноват, разумеется, а DBA проекта.

                    Yii, несомненно, дрянь еще та. Но не стоит перекладывать на PHP-фреймворк ответственность за кривизну архитектуры базы данных и думать, что фреймворк вам тут сейчас всё магически разрулит.
                      +1
                      Не зная броду, не суйся в воду


                      Видимо, у Вас совсем нет опыта с Yii, раз вы его так поливаете. Очень даже неплохой фреймворк. Как говорится, проблема в прокладке между рулем и сиденьем.
                        +1
                        Вы неправы. Опыта с Yii у меня достаточно. И я имею все основания не любить этот фреймворк.

                        Интересно другое — что такого оскорбительного для себя вы нашли в моем комментарии, что немедленно пустились в ответные оскорбления? Какие ваши чувства задеты?
                        –3
                        Вы хотите сказать, что есть возможность спроектировать реляционную БД с миллионными табличками так, что производительность сильно нагруженного приложения, построенного с применением YII AR будет сопоставима с производительностью того же приложения, использующего для доступа к данным «простые запросы»?
                          +3
                          Если запросы из приложения на Yii будут возвращать десятки записей, т.е. фреймворку придется создавать только десятки AR, то вполне сопоставимы. Скажем так, конечный пользователь не заметит разницу.
                          Но если вы имеете ввиду, что запросы будут возвращать 100500+ записей, то от AR надо отказаться.
                            +2
                            если вы имеете ввиду, что запросы будут возвращать 100500+ записей, то от AR надо отказаться

                            От запросов таких нужно отказаться. Нет никакой необходимости тащить на сторону PHP тысячи и более записей из БД. Если же такая необходимость возникает — пора заняться аудитом архитектуры. И зарплат разработчиков.
                              0
                              Зачем же так категорично. Лично мне пришлось такую задачу решать. Банальный экспорт данных. Их может быть много и их надо тащить на сторону PHP.
                              Сперва пробовал CActiveDataProvider, таскал по 100 записей. Получилось невыносимо медленно. Переделал на CArrayDataProvider и все зашевелилось.
                                0
                                О подобных кейсах я во всей этой ветке и говорю.
                                0
                                Вот прям сразу аудитом архитектуры? Даже если задача свормулирована как «отобразить 100500 записей»?)
                                  +1
                                  Вряд ли тот, кто ставил такую задачу, действительно хочет на одном экране видеть более 100 тысяч записей. Уточните задачу для начала ))
                                    0
                                    Бывало и такое, что нужно очень много записей на одном экране, и это именно то, что хотели те, кто ставили такую задачу. В прочем, я уверен, что разницу очень легко заметить и на меньших количествах данных, я возможно даже провести несколько синтетических тестов для установления примерного порядка этой разницы, если не обленюсь.

                                    Конкретно в нашей команде, после названного Вами выше аудита архитектуры, мы внутри команды (не маленькой и не дешевой) пришли как-раз к тому, что от использования AR в пользовательской части системы имеет смысл отказаться, так как оверхед по ресурсам не стоит удобства, которое приносит использование данного шаблона.
                                      0
                                      Я вас не понимаю.

                                      Для меня ActiveRecord — это просто два метода save() и delete() у объекта. Какой оверхед по ресурсам вам создают эти два метода? Зачем нужно от них отказываться?

                                      Поясните, пожалуйста.
                              0
                              А что такого экстраординарного в «миллионных табличках»?

                              Даже для MySQL без всякого тюнинга таблицы на 10**6 — 10**7 записей не составляют никаких проблем. Я уж не говорю о более «взрослых» СУБД.

                              И да. Я не знаю, что такое «сильно нагруженное приложение» в вашем комментарии. Вы в Badoo работаете? Или в Mamba? А может быть mail.ru? Нет? А откуда у вас тогда нагрузки? Ах, от собственной же архитектуры…
                                0
                                При чем тут СУБД, если мы говорим о конкретной реализации конкретного шаблона проектирования, а если точнее о ее минусах? И при чем тут мое место работы, оно как-то влияет на эту эти минусы? Я всего лишь говорю, что данная реализация не подходит для нагруженной работы с крупными данными, и у меня есть примеры, когда в продакшене от этого было реально больно. Вы утверждаете, что дело в архитектуре БД/Приложения, возможно, вы сможете привести контрпример?)
                                  +3
                                  Я могу вам привести множество примеров и контрпримеров. Но, боюсь, вы меня не поймете, если для вас «количество записей в таблице» == «нагрузка»

                                  Разговор бессмысленный.
                                  — не тащите на сторону PHP много данных из базы, берите только необходимое
                                  — используйте базу, как СУБД, а не как хранилище, переносите логику выборки на сторону базы
                                  — не используйте MySQL
                                  — не используйте без нужды сложные relations в Yii, без четкого понимания, какие именно запросы генерируются
                                  И будет вам счастье.

                                  А если вам вдруг мешает реализация ActiveRecord в Yii — подумайте, может в танцоре дело?
                                    0
                                    Я нигде не приводил равнозначности нагрузки и количества записей в БД, прошу прощения, если неправильно формулировал.
                                    Я ничего не имею против реализации AR в целом, я просто пытаюсь сказать, что ее использование уместно не всегда. Вы же меня как будто не слышите и тычите мне в лицо очевидными постулатами.
                                      +2
                                      Будьте точнее в формулировках — и не будет в ваш адрес очевидных постулатов.

                                      я просто пытаюсь сказать, что ее использование уместно не всегда

                                      Ну не всегда. И что? Никто и не утверждал, что «AR — всегда!»

                                      А в целом я рад, что мы услышали друг друга.
                                      –2
                                      >не используйте без нужды сложные relations в Yii

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

                                      Кстати, Yii 1.1 не способен отобразить связанную модель связанной модели. :)
                                        0
                                        способен
                                          0
                                          И каким же образом можно обратиться к профилю автора в
                                          $posts = Post::model()->with('author.profile')->findAll();
                                          ?
                                            0
                                            вопрос уточните. В комменте вы написали про отображение связанной модели, а сейчас пишете про обращение к модели. Конкретнее кейс укажите.
                                              –1
                                              Что не ясно? :)
                                              Как вытащить данные из profile?
                                                +3
                                                неясно то, что я написал комментом ранее — вы в разных комментах по разному сформулировали проблему.

                                                $profile = $post->author->profile;
                                                  –1
                                                  $post->author->profile выводит только первичный ключ
                                                  Обратиться к
                                                  $post->author->profile->name уже не выходит,
                                                  Вышло так:
                                                  $post->author->getRelated('profile')->name

                                                  Не совсем в одном стиле :)
                                                  И в документации это почему-то не отражено.

                                                    +2
                                                    >>> $post->author->profile->name уже не выходит,

                                                    это чисто ваша какая-то проблема с описанием связи. Связи работают именно в едином стиле.
                                                      +3
                                                      Подозреваю, что у вас поле в БД тоже называется profile (а надо называть profile_id), и при обращении читается прямое значение атрибута, а не вызывается геттер для связи.
                                0
                                Ну, разница в производительности выполнения одного и того же запроса, построенного через тот же command и те же criteria легко может составлять до десятка раз.
                                –1
                                1) DefaultScope / Lifecycle Callbacks (beforeSave, afterUpdate) — зло, не используйте их никогда
                                2) ActiveRecord хорош до тех пор, пока вы не переборщите с магией. Как только появляются симптомы bottleneck в ActiveRecord — бежим к DataMapper/QueryBuilder
                                  0
                                  1) Слишком категоричное утверждение. DefaultScope является хорошим решение для некоторых кейсов. before / after стоит использовать с осторожностью, но в некоторых случая они бывают полезны. Инструмент не зло, а помощник, если им владеть. В той же doctrine, event based hooks имеют место быть, у событий есть свои сценарии применения, полезности и сложности.
                                  2) С магией всегда стоит быть осторожным, на то она и магия) Я стараюсь избегать.
                                    0
                                    Ага, запустили проект так, что-то изменили, а тут вдруг появились бутылочные горлышки.
                                    Нужно все переписывать.
                                    Это типа строили дом, а потом его нужно сломать и заново построить :)
                                    Шикарно.
                                    Архитектура на все 100.
                                    А, ну да, хоумпаджи с такими проблемами не столкнутся, что намекает на что расчитан AR.
                                    –2
                                    +100500 про маленькие сайты.

                                    Не знаю, почему минусуют :)
                                    +1
                                    Я бы не сказал, что у Yii низкий порог входа. Как ни крути, но для работы с фреймворком нужно хотя бы немного понимать ООП, знать некоторые паттерны, научиться генерировать модели. Новичок вряд ли сможет осознанно разработать приложение, разве что поставить и запустить, как делают с CMS.

                                    У Yii есть три очень весомых преимущества — хорошая документация, качество фреймворка и большое сообщество. Первое и второе способствует привлечению новых программистов и познанию фреймворка. Третье — грамотным консультациям, разработке новых дополнений и переработке фреймворка. На выходе мы получаем хороший и популярный продукт.
                                    Здесь стоит кинуть палку в сторону Angular. Документация никакая, сообщество маленькое. Как результат имеем скверный фреймворк и малое количество специалистов.
                                      +1
                                      Но простите, репо angular1 48,787 звезд, yii2 7,957. Более того, angular распространен повсеместно, а yii2 большей частью на территории СНГ.

                                      Относительно минусов yii2, главным на мой взгляд минусом является гвоздями приколоченное ActiveRecord и отсутствие в документации инструкций по интеграции DataMapper, что влечет за собой непопулярность TDD\DI\DDD практик в сообществе.
                                      Так же к минусам (а возможно и к плюсам) следует отнести явную нацеленность фреймворка на прототипы, об этом говорит обилие странных виджетов, вроде Pjax\Modal\Nav\Carousel, полезных на этапе прототипа, но слишком сложных в кастомизации для продакшена.
                                        0
                                        мне понравилась фраза автора статьи про «прототип выкидывать». Yii — RAD-фреймворк, и действительно хорош для прототипирования: набросали, нагенерили — работает. А дальше начинаем программировать с нуля на инструменте без навязанной архитектуры. Рядовой же член сообщества Yii уверен, что фреймворк популярен из-за своего качества и удобства и подходит для любых задач, ничего не знает о техническом долге, и ничего не слышал о ddd/solid/tdd. И продолжает набивать в модель следующую тысячу строк: «ну не еще же один класс создавать»/«сервис? это сложно!».
                                          0
                                          Строили, строили дом, а потом взяли, передумали, развалили и начали строить заново :)
                                            0
                                            нет, построили за ночь дом из говна и палок, чтобы показать как это будет выглядеть.
                                              0
                                              То есть Yii таки говно?

                                              И это какой-то странный подход к разработке. :)
                                                0
                                                я про yii не писал.
                                                Это не подход к разработке, а способ быстро набросать концепт например для показа инвестору.
                                        +1
                                        немного понимать ООП и научиться тыкать кнопки — это и есть низкий порог входа. Знать некоторые паттерны для yii не надо.
                                        Именно этот низкий порог и способствует наряду с хорошей документацией привлечению новых программистов, но ни в коем случае не качество. Если фреймворк и работает, то уровень 99% сторонних расширений ниже плинтуса. И все это опять же следствие низкого порога. Низкий порог => большое сообщество программистов низкого уровня. Популярность всегда напрямую коррелирует с уровнем. Это просто данность.
                                          +1
                                          Кодеры и под этот порог не подходят. А их очень и очень много.
                                          Развернуть прототип действительно может программист начального уровня, но написать нормальное приложение — нет.

                                          Yii подходит для большинства задач. Ведь в большинстве своем сайты достаточно просты (визитки, корп-порталы, простые crm).
                                          Если система достаточно сложна, естественно, используют другие решения. Да и уровень задействованных программистов гораздо выше.
                                          0
                                          >знать некоторые паттерны, научиться генерировать модели
                                          Можно поподробнее?
                                            0
                                            Ну совсем новичкам вообще не стоит начинать с фреймворков.
                                            Выростут неумехи не знающие ни фреймворка, ни языка, не умеющие ступит и шагу самостоятельно.
                                            0
                                            А как вы видите перспективы фреймворка Yii (пока второй версии) в будущем? В беседах с коллегами по цеху, всплывает тема, что это умирающий фреймворк, имеет ли смысл начинать учить его сейчас?
                                              +2
                                              умирать ему смысла нет. как первый фреймворк джуниора он вполне подойдет — решает множество задач, есть готовые решения, дает некое представление о строении фреймворков, не перегружая архитектурой.
                                                0
                                                а если не джуниор, но проекты небольшие и тащить симфони нет смысла?
                                                  0
                                                  смотря какие цели и потребности. мне как программисту, желающему развиваться в профессии, неинтересно делать проекты на yii. Но в разговоре о программировании часто вспоминают деньги — за это я ответить не могу.
                                              0
                                              Добрый вечер!
                                              Интересная статья, понравилась.

                                              Сейчас работаю над крупным строительным порталом(пользователи, компании, товары, лоты, комментарии, статьи, монетизация, личные сообщения и т.д.), который уже разрабатывается год. Никаких тестов там не используется и я подумываю начать покрывать тестами имеющийся функционал, чтобы спокойно двигаться дальше.
                                              В связи с этим прошу совета, с чего лучше начать покрытие теста подобного проекта. Опыт в тестировании совсем незначительный, поэтому важно Ваше мнение.
                                              Спасибо!
                                                0
                                                Скорее всего, если код писался на протяжении года без тестов, с ним в нагрузку идёт существенный технический долг, и он будет сопротивляться тестированию. Учитывайте, что одно из главных преимуществ unit-тестирования, не в верификации правильности программы (этим QA-инженеры должны заниматься или профессиональные тестировщики), а в том, что тесты улучшают архитектуру приложения на уровне кода. Иными словами, чтобы код был тестируемым, Вы будете вынуждены делать его более модульным, менее связанным и простым.
                                                Покрывать тестами существующий код, без хорошего опыта в тестировании и существенного рефакторинга, может оказаться невыполнимой задачей.
                                                Возможно, на первом этапе, будет проще попробовать новый функционал писать через тесты: сперва тесты — потом код.
                                                Рекомендую так же, если ещё не читали, почитать книгу Кента Бека: очень доходчивая методичка о разработке через тестирование на простых и очевидных примерах.

                                                  0
                                                  Очевидно же, с того, что чаще всего используется… :)
                                                  0
                                                  Так дело в том, что Yii рекомендует жирные модели:
                                                  www.yiiframework.com/doc/guide/1.1/ru/basics.best-practices#sec-2
                                                  :)
                                                    0
                                                    Вы лукавите, выдёргивая один тезис из контекста. Там же написано:
                                                    Иногда следование последнему правилу делает модель очень толстой, то есть содержащей очень много кода в одном классе. Это может привести к трудностям поддержки кода в том случае, если модель используется для выполнения различных задач.… Для небольших и средних приложений это допустимо. Для крупных же приложений в целях упрощения дальнейшей поддержки кода можно сделать следующее:

                                                    Далее идёт пример разделения ожиревшей модели при помощи наследования. Но, как я писал и статье, композиция предпочтительнее наследования, хотя и несколько сложнее в реализации.
                                                      0
                                                      Я в курсе о наследовании. Но это уже ООП головного мозга.
                                                      Про это есть в статье: http://blog.kpitv.net/article/frameworks-1/

                                                      Да и все апологеты фреймворков за жирные модели почему-то.
                                                      Аж странно.
                                                        0
                                                        хорошим подходом считается модель как сущность, обладающая различным поведением в рамках бизнес-задач, относящихся непосредственно к этой модели. В мире же yii модель используется как смесь сущности, сервисов, вью-хелперов, репозиториев и всего всего, что может косвенно к модели относиться.
                                                    –2
                                                    В стате почему-то смешаны лучшие практики с личным опытом, не совсем касающимся этих практик :)
                                                      0
                                                      >Программируйте с использованием языка, а не на языке.

                                                      Во-во. А то выростают программисты на одном фреймворке, не меющие шагу самостоятельно ступить без костылей. :)
                                                        0
                                                        Из всех критикующих комментариев складывается впечатление, как будто Yii всей своей сущностью и натурой заставляет программиста писать неэффективный/буксующий код, а все остальные фреймворки — нет. По-моему все зависит от программиста, его компетенции в PHP в целом и в Yii в частности!
                                                        Как говорится, нечего на зеркало кивать, коли рожей не вышел.
                                                          +2
                                                          Нет конечно, но разработчики люди ленивые, и если брать новичков — они редко задаются вопросом «правильно ли я делаю». Если чего-то нет из коробки или какой-то подход не навязывается фреймворком будут делать как попало. Добавить к этому простоту самого фреймворка (низкий порог входа если хотите) и получается совсем плохо. Причем потом слышишь от этих людей фразы в духе «контейнер зависимостей хуже для тестирования».

                                                          В руках сильного разработчика Yii вполне себе годный фреймворк. Либо под контролем сильного разработчика. Но только как правило у этого сильного разработчика Yii далеко не первый фреймворк и он знает когда оно хорошо а когда не очень.
                                                            –1
                                                            Все фреймворки заставляют писать буксующий код :)

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