Разделение приложения на слои

Обсуждаем, как правильно строить приложения
nepster
Сообщения: 838
Зарегистрирован: 2013.01.02, 03:35

Re: Разделение приложения на слои

Сообщение nepster »

zelenin писал(а):https://github.com/dddinphp в тему.
кто купит книгу, расшарьте для коллег)
Давайте я вас познакомлю вот с таким вот ресурсом: https://skladchik.com

lynicidn писал(а):извиняем :D
переходим на симфони2? )
На самом деле веб контроллер у тебя и ничего страшного что он отдаст строку вместо респонзе объекта и я так понимаю *Command extends Model ?
а не слишком много моделей? почему не уместить все в $form ?
подход интересен за исключением того, что вы хотите убить 2х зайцев сразу, универсальный контроллер, но они разные изначально yii/console yii/web - тут я не заморачиваюсь и это остается в уии стайл, если вы не ставите цель шифровать уии код, то смысда в этом 0

я тоже не работаю с ар в контроллерах, почти, там где нужна обработка пользовательского ввода - у меня 1 модель форма (как правило) и сценариями и методами это модели уже работаю в контроллере, выглядит в уии стайл с соблюдением BC (совместимо с gii)
По поводу перехода на симфони2, там так-же есть свои плюсы и свои минусы, плюсы в четкой крутой архитектуре, а минусы в скорости. Симфони очень медленный фреймворк, а если выключить кэш, это капец полный.

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

Я где-то слышал такую фразу, что если посадить 10 сеньеров решать 1 задачу, они друг друга поубивают из-за споров, каким подходом ее решать.

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


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


П.С. Модераторы, перенесите пожалуйста тему в раздел viewforum.php?f=28
Это не вопрос, это не вопрос по программированию, это тема для улучшения архитектуры кода на yii2.

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Разделение приложения на слои

Сообщение zelenin »

nepster писал(а):Давайте я вас познакомлю вот с таким вот ресурсом: https://skladchik.com
я могу себе позволить потратить 10 долларов) но не всегда хочу это делать. А если не хочу 10 тратить, то не хочу и 1.

Аватара пользователя
samdark
Администратор
Сообщения: 9362
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Разделение приложения на слои

Сообщение samdark »

Ну, это точно не документация и не рецепт.

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Разделение приложения на слои

Сообщение zelenin »

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

Аватара пользователя
samdark
Администратор
Сообщения: 9362
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Разделение приложения на слои

Сообщение samdark »

Ну... не так уж и быстро. К тому же, кеш — это сложно. С инвалидацией можно круто огрести.

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Разделение приложения на слои

Сообщение zelenin »

Sam Dark писал(а):Ну... не так уж и быстро. К тому же, кеш — это сложно. С инвалидацией можно круто огрести.
имеется в виду компиляция в php

nepster
Сообщения: 838
Зарегистрирован: 2013.01.02, 03:35

Re: Разделение приложения на слои

Сообщение nepster »

zelenin писал(а):
nepster писал(а):Давайте я вас познакомлю вот с таким вот ресурсом: https://skladchik.com
я могу себе позволить потратить 10 долларов) но не всегда хочу это делать. А если не хочу 10 тратить, то не хочу и 1.
Там книга вышла по yii2 на русском, так момент в том, что в России она стоит 700 - 900 рублей, а в украине в 2,5 раза дороже и тут уже вопрос не в деньгах, а в принципе =).

zelenin писал(а):
nepster писал(а):По поводу перехода на симфони2, там так-же есть свои плюсы и свои минусы, плюсы в четкой крутой архитектуре, а минусы в скорости. Симфони очень медленный фреймворк, а если выключить кэш, это капец полный.
суть в том, что архитектура симфони не подразумевает ее использование без кэша) что в принципе нормально. Девелоперу например удобно конфигурить аннотациями, на деве аннотации читаются в рантайме, все медленно, на проде аннотации, шаблоны и прочая компилируются в php, все работает быстро.
Я когда работал с симфони, я сразу полюбил аннотации, но тем не менее поддерживать конфиги в php, xml и yml одновременно, мне показалось очень сомнительной идеей. Так-же после работы например с переводами (не помню как там было, аналог Yii::t) каждый раз в ручную в консоле нужно было сбрасывать кэш, с не привычки я это постоянно забывал делать и не понимал почему ничего не работало. Но самый ад меня ждал, когда я допиливал приложение, в браузере каждый раз оно грузилось более 10 секунд (дев версия), после этого плевал я на эту симфони с большой горы.

+ опять таки, есть очень много разных фреймворков и всегда во всех будут свои плюсы и минусы. Нет супер идеального продукта. Поэтому нет никого смысла спорить на какой фреймворк переходить или какой фреймворк хуже или лучше. Симфони гдето лучше yii, yii где-то лучше симфони.

Sam Dark писал(а):Ну, это точно не документация и не рецепт.
Александр при всем уважении yii framework напоминает php, в том смысле что его засрать можно очень легко.
Я говорю о том, что нет советов или примеров лучших практик по yii2 (да в доках там иногда что-то в 2 словах проявляется). Вы писали/пишите отличную книгу рецептов, примеры приложений, но все это очень легко с вероятностью 95% превращается в свалку.

А все почему, потому, что нет четких примеров и рекомендаций как правильно готовить yii2. Например симфони практически не позволяет выйти за рамки своей идеологии наговнокодить в структуре там намного сложнее, yii2 же не устанавливает никаких барьеров и в результате появляется большой соблазн и возможность наговнокодить. И как только проект приближается к среднему и далее, то тут будут очень большие проблемы.

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

И когда на тостере зададут очередной вопрос "какой framework выбрать?", я не хочу видеть там ответы от "бородатых дядек", что yii это игрушка для сайтов уровня блог.

Понимаете о чем я ?

А вот в таких разделах "общие вопросы" тема быстро затеряется ну и собственно никакого развития в этой сфере не будет.

Аватара пользователя
vova07
Сообщения: 1004
Зарегистрирован: 2012.11.29, 14:52
Откуда: Chisinau, Moldova

Re: Разделение приложения на слои

Сообщение vova07 »

Кому нужна книга пишите в ЛС, поделюсь.
Из уважения к автору книги, в паблик выкладывать её не буду. 13 баксов это не деньги, а автора я думаю они вполне порадуют. Так что если кому-то не жалко поддержите его. А если поддержать не охота, то я с вами поделюсь но только в приват.

Аватара пользователя
samdark
Администратор
Сообщения: 9362
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Разделение приложения на слои

Сообщение samdark »

Утащил тему в документацию. Задумку понял, поддерживаю на 100%.

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

nepster
Сообщения: 838
Зарегистрирован: 2013.01.02, 03:35

Re: Разделение приложения на слои

Сообщение nepster »

Sam Dark писал(а):Утащил тему в документацию. Задумку понял, поддерживаю на 100%.

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

Я сейчас готовлю не большое приложение на yii2 (в виде блога), хочу его красиво оформить по вышеуказанным примерам темы. Будет здорово, если вы тоже прокомментируете.

Аватара пользователя
xoma
Сообщения: 641
Зарегистрирован: 2009.04.02, 15:24
Откуда: Ногинск
Контактная информация:

Re: Разделение приложения на слои

Сообщение xoma »

Вот еще хорошая книжка - https://leanpub.com/cleanphp
На практике показано каким образом сохранять код более или менее независимым от фреймворка.
Приведен пример миграции с Zend на Laravel.
В книге хорошо расписаны Repository, Factory и Adapter паттерны.

nepster
Сообщения: 838
Зарегистрирован: 2013.01.02, 03:35

Re: Разделение приложения на слои

Сообщение nepster »

Собственно попробовал я повторить все вышеупомянутое на примере и возникло еще больше вопросов, чем было.

Попробую все подробно расписать. Пример начал делать работая над блогом и рассматриваем сущность Article.

Архитектура следующая:

Код: Выделить всё

 - controllers
   - backend
   - frontend
 - interfaces
 - migrations
 - models
   - backend
       - ArticleSearch.php
       - ArticleForm.php
   - frontend
       - ArticleForm.php
       - ArticleSearch.php
     Article.php
     ArticleQuery.php
     ArticleRepository.php
     ArticleService.php
 - views
   - backend
   - frontend
 - widgets
   Bootstrap.php
   Module.php
В любом случае архитектуру лучше всего всегда делать модульной и сразу предполагаем, что модуль будет отвечать как за frontend, так и за backend

Идем дальше, контроллер выходит примерно вот такого содержимого:

Код: Выделить всё

    /**
     * Создать
     * @return string
     */
    public function actionCreate()
    {
        $model = new ArticleForm();

        if (Yii::$app->request->isPost) {
            $service = new ArticleService();
            $model->load(Yii::$app->request->post());
            if ($model->validate()) {
                $service->create($model);
            }
        }

        return $this->render('create', [
            'model' => $model,
        ]);
    }

    /**
     * Обновить
     * @param $id
     * @return string
     * @throws NotFoundHttpException
     */
    public function actionUpdate($id)
    {
        $model = new ArticleForm();
        $modelRepository = ArticleRepository::findById($id);

        if (!$modelRepository) {
            throw new NotFoundHttpException("Страница под номером '{$id}' не найдена");
        }

        $model->setAttributes($modelRepository->getAttributes());

        if (Yii::$app->request->isPost) {
            $service = new ArticleService();
            $model->load(Yii::$app->request->post());
            if ($model->validate()) {
                $service->update($model, $modelRepository);
            }
        }

        return $this->render('create', [
            'model' => $model,
        ]);
    }

    /**
     * Удалить
     * @param $id
     * @return mixed
     * @throws NotFoundHttpException
     */
    public function actionDelete($id)
    {
        $modelRepository = ArticleRepository::findById($id);

        if (!$modelRepository) {
            throw new NotFoundHttpException("Страница под номером '{$id}' не найдена");
        }

        $service = new ArticleService();
        $service->delete($modelRepository);

        // Redirect
    }
Как мы договорились, основная модель ничего не содержит кроме стандартных методов (Article.php):

Код: Выделить всё

class Article extends \yii\db\ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%articles}}';
    }

    /**
     * @return ArticleQuery
     */
    public static function find()
    {
        return new ArticleQuery(get_called_class());
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => '№',
            'slug' => 'Слаг',
            'title' => 'Заголовок',
            'short_text' => 'Краткое описание',
            'full_text' => 'Полное описание',
            'meta_title' => 'Заголовок (Title)',
            'meta_description' => 'Описание (Description)',
            'meta_keywords' => 'Ключевые слова (Keywords)',
            'visible' => 'Отображение',
            'time_create' => 'Дата создания',
            'time_update' => 'Дата редактирования',
        ];
    }
}
Кастомные квери (ArticleQuery.php):

Код: Выделить всё

class ArticleQuery extends ActiveQuery
{
    /**
     * @param int $state
     * @return $this
     */
    public function visible($state = 1)
    {
        $this->andWhere([Article::tableName() . '.visible' => $state]);
        return $this;
    }
}
 


Репозиторий, который отвечает за выборку (ArticleRepository.php)

Код: Выделить всё

class ArticleRepository extends Article
{
    /**
     * Получить запись по идентификатору
     * @param $id
     * @param int $visible
     * @return array|null|\yii\db\ActiveRecord
     */
    public static function findById($id, $visible = 1)
    {
        return self::find()
            ->where(['id' => $id])
            ->visible($visible)
            ->one();
    }
}


Сервис, который отвечает за сохранение/редактирование и удаление данных (ArticleService.php)

Код: Выделить всё

class ArticleService
{
    /**
     * Сохранить
     * @param Model $article
     * @return bool
     */
    public function create(Model $article)
    {
        $model = new Article();
        $model->setAttributes($article->getAttributes());
        return $model->save(false);
    }

    /**
     * Обновить
     * @param Model $article
     * @param Article $repository
     * @return bool
     */
    public function update(Model $article, Article $repository)
    {
        $repository->setAttributes($article->getAttributes());
        return $repository->save(false);
    }

    /**
     * Удалить
     * @param Article $repository
     * @return false|int
     * @throws \Exception
     */
    public function delete(Article $repository)
    {
        return $repository->delete();
    }
}


Форма, которая получает и обрабатывает данные (ArticleForm.php)

Код: Выделить всё

class ArticleForm extends \app\modules\articles\models\Article
{
    // Наследуемся от Article (ActiveRecord), чтобы избежать перечисления всех нужных свойств

    /**
     * @inheritdoc
     */
    public function transactions()
    {
        return [
            'user-create' => self::OP_ALL,
            'user-update' => self::OP_ALL,
        ];
    }

    /**
     * @inheritdoc
     */
    public function scenarios()
    {
        return [
            'user-create' => [],
            'user-update' => [],
        ];
    }

    /**
     * @inheritdoc
     */
    public function beforeValidate()
    {
        if (parent::beforeValidate()) {

            // Логика

            return true;
        }

        return false;
    }

    /**
     * @inheritdoc
     */
    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {

            // Логика

            return true;
        }

        return false;
    }

}


Теперь еще раз описание моделей:
1) Article.php - Основная Модель содержит только стандартные атрибуты ActiveRecord.
2) ArticleQuery.php - Кастомные квери (Скопы). Для удобства.
3) ArticleRepository.php - Наследуется от основной модели и содержит все необходимые методы для выборки.
4) ArticleService.php - Сохраняет (редактирует и удаляет) данные в хранилище (например в базу данных).
5) ArticleForm.php - Наследуется от основной модели, так как нам лень переопределять все нужные нам свойства для формы.
Обратите внимание: для админки и для сайта форма добавления статьи может быть разной, поэтому ArticleForm у нас несколько.



Теперь появляется список вопросов:
1) Походу я не много запутался с репозиторием и сервисом, возможно где-то ошибка ?
2) Теперь у нас у одной сущности появилось куча классов, это нормально ?
3) Что если появляется задача организовать комментарии и теги, поэтому есть необходимость в связанности, например в реляциях:
getUser(), getTags() и getComments(), хорошо было бы закатать это под интерфейсы, а вот где это рассположить ?
4) Если есть жирный модуль где одной сущностью не обойтись, например модуль объявлений (на доске объявлений).
Есть следующие сущности:
- Апартамент
- Объявление (к примеру квартира может сдаваться: на час, на день и на ночь)
- Изображения (у каждого апартамента есть изображения)
- Резерваци (есть возможность зарезервировать апартамент)
- Календарь (ведет статистику какой апартамент когда занят, а когда свободен)

Из выше представленного примера выходит, то что мы расплодим более 20 моделей на эти 5 сущностей. Так и нужно ?

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Разделение приложения на слои

Сообщение zelenin »

nepster писал(а): В любом случае архитектуру лучше всего всегда делать модульной и сразу предполагаем, что модуль будет отвечать как за frontend, так и за backend
в случае если хочется только логически разделить. В случае создания реюзабл модуля такой подход не подойдет.

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Разделение приложения на слои

Сообщение zelenin »

nepster писал(а):

Код: Выделить всё

    /**
     * Создать
     * @return string
     */
    public function actionCreate()
    {
        $model = new ArticleForm();

        if (Yii::$app->request->isPost) {
            $service = new ArticleService();
            $model->load(Yii::$app->request->post());
            if ($model->validate()) {
                $service->create($model);
            }
        }

        return $this->render('create', [
            'model' => $model,
        ]);
    }

    /**
     * Обновить
     * @param $id
     * @return string
     * @throws NotFoundHttpException
     */
    public function actionUpdate($id)
    {
        $model = new ArticleForm();
        $modelRepository = ArticleRepository::findById($id);

        if (!$modelRepository) {
            throw new NotFoundHttpException("Страница под номером '{$id}' не найдена");
        }

        $model->setAttributes($modelRepository->getAttributes());

        if (Yii::$app->request->isPost) {
            $service = new ArticleService();
            $model->load(Yii::$app->request->post());
            if ($model->validate()) {
                $service->update($model, $modelRepository);
            }
        }

        return $this->render('create', [
            'model' => $model,
        ]);
    }

    /**
     * Удалить
     * @param $id
     * @return mixed
     * @throws NotFoundHttpException
     */
    public function actionDelete($id)
    {
        $modelRepository = ArticleRepository::findById($id);

        if (!$modelRepository) {
            throw new NotFoundHttpException("Страница под номером '{$id}' не найдена");
        }

        $service = new ArticleService();
        $service->delete($modelRepository);

        // Redirect
    }
 
Что-нибудь прочли по теме?
$modelRepository = ArticleRepository::findById($id); - репозиторий - класс, реализующий паттерн Репозиторий, с помощью которого мы из произвольного стораджа ищем модели:
$repo = new Repo;
$model = $repo->find($id);

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Разделение приложения на слои

Сообщение zelenin »

class ArticleRepository extends Article - зачем наследовать? делаем отдельный класс, не наследуясь ни от чего.
class ArticleForm extends \app\modules\articles\models\Article - аналогично
>> 2) Теперь у нас у одной сущности появилось куча классов, это нормально ?
кол-во не может являться критерием.

Вообще мне все это не очень нравится, т.к. все это очень искуственно - пытаться из одной архитектуры сделать другую. Как будто изолентой прикручиваем. А если еще сильнее абстрагировать, то зачем тогда yii и нужен?

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Разделение приложения на слои

Сообщение zelenin »

если хочется на yii, то имхо нужно принять "правила игры", т.к. внутри yii все сильно связано, и чтобы ты ни делал - это тупо надстройка над старым функционалом. Бредово все это выглядит при реализации. Думаю, если хочется совершенствования надо мигрировать на более правильные продукты. В yii ничего не хотят менять в этом плане. В то время, как мир php пищит от принятия psr-7, развязывающего руки в выборе инструментов, разработчик yii2 заливает новый велосипед без поддержки стандарта (https://github.com/yiisoft/yii2-httpclient) - дичь какая-то. PSR-3 опять же не собираются внедрять. В общем такие дела)

nepster
Сообщения: 838
Зарегистрирован: 2013.01.02, 03:35

Re: Разделение приложения на слои

Сообщение nepster »

то зачем тогда yii и нужен?
Вопрос религии. Везде свои минусы и свои плюсы.

Код: Выделить всё

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

class ArticleRepository extends Article - зачем наследовать? делаем отдельный класс, не наследуясь ни от чего.
Ну опять таки как доставать данные из модели ? Добавить ее через неймспецс и обращатсья через Article::find ?
class ArticleForm extends \app\modules\articles\models\Article - аналогично
Тут главная проблема в том, что если не наследоваться то нам нужно все атрибуты указывать для формы.

И какие мысли по поводу 1 2 и 4 вопроса ?

Аватара пользователя
yiijeka
Сообщения: 3091
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: Разделение приложения на слои

Сообщение yiijeka »

Да, вот так вот делать не стоит - class ArticleRepository extends Article
Каюсь, сам так делал .... Отгрёб проблем со связями и сценариями. Article - должна быть одна и не наследуемая. Надуманный минус " Наследуемся от Article (ActiveRecord), чтобы избежать перечисления всех нужных свойств" не такой уж и страшный, по сравнению с трудностями, с которыми можно столкнуться при наследовании.
Даже вот в gii уже есть идея переделать генерацию формы поиска - https://github.com/yiisoft/yii2-gii/pull/61

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Разделение приложения на слои

Сообщение zelenin »

nepster писал(а):
то зачем тогда yii и нужен?
Вопрос религии. Везде свои минусы и свои плюсы.
это правда лишь отчасти. Нельзя катание на сломанной машине вместо исправно работающей обосновать этой фразой, особенно когда исправную ты никогда и не видел) Не повод для спора.
nepster писал(а):Ну опять таки как доставать данные из модели ? Добавить ее через неймспецс и обращатсья через Article::find ?
ну а как сейчас достаете? так и доставайте - только репо не наследуйте от модели. Иначе вы можете вызвать все методы модели Article - просто неправильно.
nepster писал(а):
class ArticleForm extends \app\modules\articles\models\Article - аналогично
Тут главная проблема в том, что если не наследоваться то нам нужно все атрибуты указывать для формы.
это не проблема. Чуть выше привел ответ и на это.
nepster писал(а):И какие мысли по поводу 1 2 и 4 вопроса ?
1. На первый взгляд не вижу проблем: репо - для выборки, сервис - вспомогательная логика.
2. Вроде ответил. Кол-во - не критерий.
4. См. п. 2

nepster
Сообщения: 838
Зарегистрирован: 2013.01.02, 03:35

Re: Разделение приложения на слои

Сообщение nepster »

yiijeka писал(а):Да, вот так вот делать не стоит - class ArticleRepository extends Article
Каюсь, сам так делал .... Отгрёб проблем со связями и сценариями. Article - должна быть одна и не наследуемая. Надуманный минус " Наследуемся от Article (ActiveRecord), чтобы избежать перечисления всех нужных свойств" не такой уж и страшный, по сравнению с трудностями, с которыми можно столкнуться при наследовании.
Даже вот в gii уже есть идея переделать генерацию формы поиска - https://github.com/yiisoft/yii2-gii/pull/61
Я вас услышал, а можно пример, где могут быть проблемы ?

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

zelenin писал(а):если хочется на yii, то имхо нужно принять "правила игры", т.к. внутри yii все сильно связано, и чтобы ты ни делал - это тупо надстройка над старым функционалом. Бредово все это выглядит при реализации. Думаю, если хочется совершенствования надо мигрировать на более правильные продукты. В yii ничего не хотят менять в этом плане. В то время, как мир php пищит от принятия psr-7, развязывающего руки в выборе инструментов, разработчик yii2 заливает новый велосипед без поддержки стандарта (https://github.com/yiisoft/yii2-httpclient) - дичь какая-то. PSR-3 опять же не собираются внедрять. В общем такие дела)
Значит у разработчиков есть какие-то причины по этому поводу.

Закрыто