Yii 2.0.10

    Вышла новая версия PHP-фреймворка Yii, включающая в себя более 80 улучшений и исправлений. Инструкции по установке и обновлению можно найти по адресу. Стоит отметить, что в релиз вошли четыре небольших изменения, которые могут повлиять на работу существующих приложений. Обязательно прочитайте UPGRADE.md.


    Спасибо замечательному сообществу за отличные пулл-реквесты и обсуждения. Без вас этого релиза не было бы! За процессом разработки Yii 2 можно начать следить, поставив звёздочку на GitHub. Подписывайтесь на наш Twitter и Facebook. Обсудить релиз можно в комментариях.


    Полный список изменений можно найти в CHANGELOG. Далее мы рассмотрим наиболее интересные.


    URL


    Новый класс yii\web\UrlNormalizer позволяет нормализовать запросы на URI с присутствующим или отсутствующим слешем в конце, что довольно важно для поисковой оптимизации. Подробное описание можно найти в разделе «URL normalization» официального руководства.


    Миграции


    Помимо небольших исправлений миграции получили и довольно значительное улучшение. Теперь можно запускать миграции из нескольких мест одновременно, если использовать для них пространства имён. Чтобы это сделать, необходимо настроить свойство migrationNamespaces консольного контроллера:


    return [
        'controllerMap' => [
            'migrate' => [
                'class' => 'yii\console\controllers\MigrateController',
                'migrationNamespaces' => [
                    'app\migrations',
                    'some\extension\migrations',
                ],
                //'migrationPath' => null, //можно отключить миграции без пространств имён
            ],
        ],
    ];

    Обработка ошибок


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


    Request


    Появился новый метод yii\web\Request::getHostName(), возвращающий имя хоста для текущего запроса.


    Не POST запросы, кодированные как multipart/form-data (например, загрузка файлов) теперь можно распарсить через yii\web\MultipartFormDataParser. Для того, чтобы этим воспользоваться, вы должны настроить Request::parsers следующим образом:


    return [
        'components' => [
            'request' => [
                'parsers' => [
                    'multipart/form-data' => 'yii\web\MultipartFormDataParser'
                ],
            ],
            // ...
        ],
        // ...
    ];

    После этого следует вызвать Request::getBodyParams() и запрос будет разобран в соответствующие переменные. В том числе в $_FILES.


    Базы данных


    Было добавлено новое поведение для ActiveRecord. yii\behaviors\AttributeTypecastBehavior позволяет автоматически приводить типы значений атрибутов.


    Типы задаются через attributeTypes:


    use yii\behaviors\AttributeTypecastBehavior;
    
    class Item extends \yii\db\ActiveRecord
    {
        public function behaviors()
        {
            return [
                'typecast' => [
                    'class' => AttributeTypecastBehavior::className(),
                    'attributeTypes' => [
                        'amount' => AttributeTypecastBehavior::TYPE_INTEGER,
                        'price' => AttributeTypecastBehavior::TYPE_FLOAT,
                        'is_active' => AttributeTypecastBehavior::TYPE_BOOLEAN,
                    ],
                    'typecastAfterValidate' => true,
                    'typecastBeforeSave' => false,
                    'typecastAfterFind' => false,
                ],
            ];
        }
    
        // ...
    }

    Если attributeTypes не задан, значение будет определяться автоматически на основе правил валидации:


    use yii\behaviors\AttributeTypecastBehavior;
    
    class Item extends \yii\db\ActiveRecord
    {
        public function rules()
        {
            return [
                ['amount', 'integer'],
                ['price', 'number'],
                ['is_active', 'boolean'],
            ];
        }
    
        public function behaviors()
        {
            return [
                'typecast' => [
                    'class' => AttributeTypecastBehavior::className(),
                    'owner' => $this,
                    // 'attributeTypes' будет задан автоматически на основе `rules()`
                ],
            ];
        }
    
        // ...
    }

    Также был добавлен yii\mutex\OracleMutex — реализация блокировки возможностями Oracle.


    Консоль


    В консоли теперь можно вызвать описание команды передав -h или --help.


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


    Шаблоны приложений были изменены, чтобы работать с недавними изменениями в Codeception. Подробнее об этом можно прочитать в новом разделе на сайте Codeception: «Yii 2.0 quickstart guide». Если вы используете шаблон проекта advanced, ознакомьтесь с его документацией по тестированию.

    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 40
    • 0
      За поведение спасибо) а то постоянно в changedAttributes ерунду получал.
      • 0
        Почему бы не использовать semver?
        • 0

          Мы его используем. Полная версия — 2.0.10.0. Просто чистые патч-релизы получаются не часто. В основном, когда крупно налажали и латаем на ходу (пока такое было, кажется, один раз за всё существование Yii).

          • 0
            Но по соглашению сем.вер. добавление фунциональности это минорное обновление. У вас же появляются новые классы, методы, а выпускается как будто патч.
            • +1
              Они используют такое соглашение по наименованию версий — 2.MAJOR.MINOR.PATCH (сейчас сменился MINOR с 9 на 10)
              • +1
                Ну да, правильно писать что-то вроде yii2 версия 0.10.0 а не yii версия 2.0.10.0 но композер так тоже понимает, так что чего уж нарушать исторически сложившийся шаблон.
                ПС: да, для нуля особые правила, я помню.
          • 0
            Круто! Очень радует, что фреймворк живее всех живых :)

            Хотелось бы ещё узнать как по поводу зависимостей от клиентских библиотек? Когдато на Хабре проскакивала статья, о том, что есть планы их убрать подальше. Это в планах осталось или от этого отказались?
            • +1

              Да, планы есть. В 2.1 или 2.2 сделаем.

              • –2
                Это же очень хорошо. От этой костыльной fxp-ссанины рыгать хочется.
              • 0
                На 2.1 запланировано, если не ошибаюсь.
              • +1
                Хорошее обновление.
                Правда, заметил одну ошибку в инструкциях по установке на сайте yiiframework.com. Для Composer Asset Plugin указана минимальная версия 1.1.1, хотя с версии 2.0.9 нужен как минимум 1.2.0.
              • +1
                Я давненько по рабочей необходимости перебрался на laravel5, однако продолжаю следить, как там у Yii2 дела продвигаются, так вот возможно я что-то пропустил или не знаю, но есть следующий список фитч, которых нет в (или я об этом не знаю):

                Seeds: — возможность наполнения базы данных тестовыми данными. В Yiii2 такое можно делать в миграциях, однако в laravel5 это сделанно в виде отдельной команды, что дает возможность получить как голую схему базы данных, так и заполнить ее тестовыми данными.

                Composers: — весьма интересная штука, которая позволяет внедрять данные в одну и/или более вьюшек. Что-то похожее на виджеты, такой себе класс, который может содержать логику и передать некоторые данные в вид. Что бывает удобно, например когда нужно передать одни и те-же данные в несколько страниц.

                Middleware: — во круг этого крутилось множество обсуждений, но я упустил конкретный ответ. Все останется по прежнему, тоесть поведения (фильтры и тп.) или все-же Middleware будут жить в Yii2?
                (хеш тег: Yii2, give a chance to Middleware)

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

                И так-же присоединяюсь к тому, что нужно разбить Yii2 на отдельные компоненты. Что мне нравится в этом инструменте, что почти о любом наркоманстве, о котором я могу подумать, оно уже есть. Я имею ввиду хелперы или вспомогательные методы (например сравнение 2 объектов активрекорд https://github.com/yiisoft/yii2/issues/9036, equals вместо === и много еще чего интересного в хорошем смысле).

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

                В общем было бы здорово получить комментарии от разработчиков по теме.
                • +2
                  Аналог Seeds — это Fixtures
                  http://www.yiiframework.com/doc-2.0/guide-test-fixtures.html
                  • +1

                    Seeds — fixtures.


                    Composers — может быть удобно в отдельных случаях, но вообще штука спорная. Таскает данные довольно неявно. Легко просадить производительность, легко перекрыть локальной переменной, не сильно приятно дебажить, когда не ясно сходу, откуда прилетела переменная.


                    Middleware — не в 2.1, но мы не перестаём обдумывать, нужно ли оно и в каком виде. По сути у нас уже примерно то же, только не по PSR. Используется извне, например, Codeception.


                    Про Requests не понял, про что именно речь. Можно ссылку?


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

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


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

                    Факт. Хотя даже у REST API исключительно под телефоны есть лендинг...

                    • 0
                      Seeds — fixtures. Да, я когда-то сталкивался, но поработать не довелось. Засовывал данные в миграции.

                      Согласен с Composers, но можно придерживаться неких правил именования например: $composerMyVar.
                      Тоесть все переменные, которые начинаются с composer будут приходить именно от туда, очевидно, понятно и сложнее перетереть.

                      https://laravel.com/docs/5.3/requests
                      По сути в 2 словах, я могу гарантировать, что в контроллере будут уже валидные данные. Вот кстате не большой пример https://mattstauffer.co/blog/laravel-5.0-form-requests.

                      «Факт. Хотя даже у REST API исключительно под телефоны есть лендинг...», он может быть сделан на другой платформе или с помощью angular2 и тп.
                      • 0
                        Согласен с Composers, но можно придерживаться неких правил именования например: $composerMyVar.
                        Тоесть все переменные, которые начинаются с composer будут приходить именно от туда, очевидно, понятно и сложнее перетереть.

                        Не знаю… костыльно как-то.


                        https://laravel.com/docs/5.3/requests

                        По сути это form model.

                        • 0
                          Да, но тут удобно еще. что Laravel5 сам все инжектит и проделывает. Плюс я после Yii2 достаточно быстро привык к тому, что в Laravel5 все разбили очень жестко. Это весьма удобно, в Yii2 вы как-то все соединили очень жестко. Тоесть то, что по факту можно расписать в 5 классов, влазит в одну модель.
                          • +1
                            А зачем разделять?
                            У любого правила цель одна — повысить эффективность.
                            Вот многие ругают Yii за то, что валидация в модели. мол не SOLID-но.
                            Но ТАК УДОБНЕЕ. Я когда начал писать свой фреймворк, то пошел по пути Юии.
                            Потом углубился в этом подходе еще больше. У меня правила это не только валидация а просто правило работы с полем. У него есть и свой аналог авфтерЛоад и бефорСаве (привязанные к конкретному полю), и валидация и другие обработчики. Выходит если я указал полю правило int то я этим сказал что оно при загрузке из базы приводится к целому, при валидации — приводится и валидируется. Повесил на него defaultValue и при чтении значения из поля — NULL меняется на значение, но оно не попадает в базу, а остается NULL, а указав defaultSaveValue наоборот — при сохранении оно сохранится. Так удобно. Да, более «кошерно» было бы сделать например так как сделали тут — отдельным поведением. Но зачем? В тех 5% случаев где стандартного поведения не хватит можно будет просто создать свое правило, благо они простые и копипаст никто не отменял.
                            В особо сложных случаях можно и методы в модели соответствующие переопределить.
                            Потом я пошел еще дальше. Я вынес связи в правила. Ведь и поле и связь это виртуальное свойство объекта. Зачем? Ну тут больше упрощение кода из соображений солидности чем удобство работы, но удобство не страдает, и можно всегда довесить на это виртуальное поле другие правила, или даже заменить его без изменения прочего кода, что дает большую гибкость.

                            следующая итерация у меня была еще более спорная. К ней и веду:
                            Значительная часть контроллеров представляли из себя CRUD в админке.
                            У меня есть базовый контроллер у которого есть виджет выводящий форму, которая активформ, но разбитая сразу на закладки. Когда у объекта полсотни полей, то всегда удобно вынести их по разным закладкам. Естественно чтобы не перечислять поля по закладкам это выносится в настройки. Держать эти настройки во вьюве неудобно. Мы плодим лишние шаблоны. Которые не отличаются.
                            По факту место настройкам разделяющим поля по группам — в контроллере.
                            Так и сделал.
                            Но в процессе реальной разработки часто бывает поля появляются и исчезают.
                            При таких изменениях нужно отразить изменение в конфиге модели, в конфиге контроллера и в языковом файле. Лезть в три файла муторно. Проще в два, ибо от языка особо не избавишься, тут ломается функционал. Поэтому настройки разделения полей модели на группы я унес в настройки модели. Это может и не так кошерно, но это практично и экономит время разработки, уменьшает колво ошибок и все такое.

                            Не призываю к тому чтобы идти моим путем. Я лишь защищаю рациональность того чтобы валидация была в модели. Так удобнее.
                            • +1
                              а Вы понимаете, что такое модель?
                              • +1
                                В данном контексте речь идет про AR. Но смешивание этих понятий не так уж и важно.
                                Модель отображает нечто из предметного мира в програмном окружении. Данные, объект и т.п.
                                Я понимаю что сферическая модель может быть вообще без атрибутов и явно не влазить в паттерн активРекорд, но на практике важнее удобство в 90% случаях, которое не лишает возможности пусть и менее удобно решить оставшиеся 10% задач.
                                А так то Ваш вопрос уж очень общий.
                                В стиле Ларавел.) Не согласны — скажите в чем. Увидели ошибку, пусть даже терминологическую — скажите где. А так то звучит стремновато. Раскройте мысль, будьте добры.
                                • +1
                                  Речь скорее о подходах как laravel5, так и Yii2, в этих инструментах сидит ActiveRecord, за несколько лет работы с ним, у меня почему-то начинает вырабатываться дикая аллергия на него. Так-как по большей части в сообществах принято считать, что модель == 1 файл (а точнее класс унаследованный от ActiveRecord).

                                  Но если чуть-чуть покапать, поделать проекты с более сложной логикой и с весьма длительной поддержкой, то ActiveRecord породит достаточно много проблем.

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

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

                                  Вообще изначально под моделью подразумевается бизнес логика по хорошему состоящая из множество различных классов, что улучшает читабельность кода, поддержку и в целом благоприятно влияет на проект. Хорошим примером будет domain model, при чем не обязательно в контексте DDD.

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

                                  И самый больный пример из своего опыта, который я могу примести это примерно следующая ситуация:
                                  Представьте, что вы работаете в небольшой конторе по разработке WEB-проектов различной сложности. Штат предположим из 5 бэкендеров в вашем подчинении. 3 из них джуны, 1 что-то похожий на мидла и вы тоже мидл, такой себе среднячковый (это я возможно о себе). Вы распределяете работу, пишите задачи, сроки горят, туда сюда, быстрее и вот потом когда вы смотрите на код работающего проекта, то все правки и доработки туда вносятся начиная с комментария «Отче наш, сущий на небесах ...».

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

                                  Честно говоря у меня много наболело по этому поводу. Поэтому я наверно извинюсь, за излишки.
                                  • +1
                                    Вы под Опенкартом поработайте. Сразу начнете любить ваших легаси-писателей как хороших кодеров)

                                    Вообще юии это такой «вордпресс для умных». В нем такого творят, что страшно.
                                    Но как правило 90% проекта это много разных вариаций на тему CRUD, с десяток взаимных связей и пляски по борьбе с собственным непониманием АПИ.

                                    Можешь сделать быстро — сделай быстро. RAD наше всё). Да, желательно соблюдать структуру и документирование и т.п., но без фанатизма. Нарушения стандартов самим Yii это малая толика зла дающая нам бонусы. Истинный ад живет в нарушениях стандартов теми кто пользуется фреймворком.
                              • 0
                                Но ТАК УДОБНЕЕ.

                                удобнее, не значит лучше.
                                и опять же стандартная аргументация: yii — rad-фреймворк, поэтому для задач, которые он решает, быстрее и удобнее — аргумент. Для крупных приложений, которые на rad-фреймворках обычно не пишутся, встроенная в модель валидация (а так же общее неследование SOLID) не прокатит.
                                • +1
                                  В том то и дело, что для своей ниши оно эффективно. Всё.
                                  Это сродни критике всего явления ORM. Мол там такие планы запросов вырастают, что уж проще делать запросы руками. Ну так и делайте. Но только там где это нужно.
                                  Пишешь на ORM, потом в уже живом окружении, уже покрытое тестами и т.п. дописываешь узкие места прямыми запросами. В процессе уточнив ТЗ, проверив все взаимодействия компонент и т.п.

                                  У юии в принципе AR тяжелые. Разделяй не разделяй, а в сложных задачах все равно выкидывать всю подсистему и писать свое. Или переписать 0.1% кода, поднажать на кеширование и доплатить лишние 20 баксов в месяц на более мощный сервер и не морочить себе голову.
                    • 0
                      Ребята, не много не по теме, подскажите как можно установить все расширения с «minimum-stability»: «stable» и сделать исключение для несколько других расширений.

                      Ситуация такая. Нужно установить kartik-v/yii2-export «dev-master», необходим функциональность с dev версий. Но при установке «minimum-stability»: «dev» все другие пакеты переходят тоже на dev игнорируя версий указанные в composer.json. Как быть?
                      • 0

                        В идеале — упросить Kartik-а тэгнуть релиз. Но должно работать, если пакету приписать @dev к версии.

                        • +1
                          или лучше номер коммита, чтобы все-таки зафиксировать версию — dev-master#c64571f892bda1298bad9c5e94ede0bc3f0e4627
                          • 0
                            можно подробнее
                            • +1
                              указать версию пакета в таком стиле в composer.json. Тем самым мы зафиксируем пакет на конкретном коммите, если стабильный релиз нам не подходит или пакет не миеет стабильного тега.
                              • 0

                                composer.json все равно будет считываться из указанной ветки, а не из коммита, так что это не всегда выход


                                https://getcomposer.org/doc/04-schema.md#package-links


                                Note: While this is convenient at times, it should not be how you use packages in the long term because it comes with a technical limitation. The composer.json metadata will still be read from the branch name you specify before the hash. Because of that in some cases it will not be a practical workaround, and you should always try to switch to tagged releases as soon as you can.

                                Может помочь объявление своего пакета:
                                http://stackoverflow.com/questions/34784809/how-to-use-a-specific-tag-version-with-composer-and-a-private-git-repository


                                "repositories": [
                                  # ...
                                  {
                                    "type": "package",
                                    "package": {
                                      "name": "vendor/package",
                                      "version": "v0.5.0",
                                      "source": {
                                        "url": "git@gitlab.server.com:vendor/project.git",
                                        "type": "git",
                                        "reference": "dd6ed3c8"
                                      }
                                    }
                                  }
                                ]
                                • 0
                                  Спасибо, попробую )
                                  • +1
                                    composer.json все равно будет считываться из указанной ветки, а не из коммита

                                    непонятно, что там с чем что. dev-master#123abc установит коммит с хэшом 123abc из ветки dev-master. Что не так по вашему?
                                    • 0

                                      Если в HEAD в composer.json будут зависимости, к примеру


                                      {
                                          "require": {
                                              "symfony/console": "3.0"
                                          }
                                      }

                                      А в dev-master#123abc


                                      {
                                          "require": {
                                              "symfony/console": "~2.7"
                                          }
                                      }

                                      То composer будет считать, что надо установить "symfony/console": "3.0" в качестве зависимости, хотя сам пакет будет установлен из указанного коммита. Это происходит потому. что пакет скачивается уже после того, как разрешены зависимости.

                                      • 0
                                        я не понимаю о чем вы. мы тут про указание зависимости в СВОЕМ проекте? если будет указан dev-master#123abc, то он и установится.
                                        • +1

                                          Он устанвится, но его зависимости будут отрезолвены неверно.
                                          В документации же все понятно:


                                          The composer.json metadata will still be read from the branch name you specify before the hash.

                                          Т.е. если указать "kartik-v/yii2-export": "dev-master#47fd3e870a1b7c8dcfe572b8290b6c61011a6aa7"


                                          То версия composer.json будет использована из мастера вместо https://github.com/kartik-v/yii2-export/blob/47fd3e870a1b7c8dcfe572b8290b6c61011a6aa7/composer.json, и если они отличаются, то будут проблемы

                                          • +1
                                            да, теперь понял проблему. Хотя формулировка очень размытая. Указанный коммит тоже находится в ветке перед хэшом, и логично что и содержимое composer.json тоже находится в этой ветке. Только речь не о ветке, а о текущем/последнем коммите указанной ветки.
                                            Т.е. указав версию в нотации dev-master#47fd3e870a1b7c8dcfe572b8290b6c61011a6aa7, мы разресолвим зависимости не из composer.json коммита 47fd3e870a1b7c8dcfe572b8290b6c61011a6aa7 ветки master, а из composer.json последнего коммита ветки master.
                                            PS. Да, это проблема.
                        • +2
                          Сасибо!
                          • 0
                            По поводу пункта «Requests» — скорее всего вы пропустили этот момент, при чтении документации, ведь тоже самое можно сделать и в Yii2. У меня в одном из проектов как раз и реализована аутентификация прежде, чем actions выполнятся.

                            Просто в контроллере добавляем поведение с необходимым способом аутентификации, при этом заранее описываем класс аутентификации наследованным от AuthMethod. При этом можно объединять сразу 2 вида аутентификации для использования в одном контроллере.

                            Вот чего действительно не хватает, так это Middleware, из-за этого иногда приходится приделывать велосипеды.
                            • 0

                              А для чего именно? Какая задача?

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