# Обновление с версии 1.1 ¶

Между версиями 1.1 и 2.0 существует много различий, так как Yii был полностью переписан для версии 2.0. Таким образом, обновление с версии 1.1 не является таким же тривиальным как обновление между минорными версиями. В данном руководстве приведены основные различия между двумя версиями.

Если прежде вы не использовали Yii 1.1, вы можете сразу перейти к разделу «Начало работы».

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

## Установка ¶

Yii 2.0 широко использует Composer, который является основным менеджером зависимостей для PHP. Установка как фреймворка, так и расширений, осуществляется через Composer. Подробно об установке Yii 2.0 вы можете узнать из раздела «Установка Yii». О том, как создавать расширения для Yii 2.0 или адаптировать уже имеющиеся расширения от версии 1.1, вы можете узнать из раздела «Создание расширений».

## Требования PHP ¶

Для работы Yii 2.0 необходим PHP 5.4 или выше. Данная версия включает большое количество улучшений по сравнению с версией 5.2, которая использовалась Yii 1.1. Таким образом, существует много различий в языке, которые вы должны принимать во внимание:

- Пространства имён;
- Анонимные функции;
- Использование короткого синтаксиса для массивов: `[...элементы...]` вместо `array(...элементы...)`;
- Использование короткого echo `<?=` для вывода в файлах представлений. С версии PHP 5.4 данную возможность можно использовать не опасаясь;
- Классы и интерфейсы SPL;
- Позднее статическое связывание (LSB);
- Классы для дат и времени;
- Трейты;
- Интернационализация (intl); Yii 2.0 использует расширение PHP `intl` для различного функционала интернационализации.

## Пространства имён ¶

Одним из основных изменений в Yii 2.0 является использование пространств имён. Почти каждый класс фреймворка находится в пространстве имён, например, `yii\web\Request`. Префикс "С" в именах классов больше не используется. Имена классов соответствуют структуре директорий. Например, `yii\web\Request` указывает, что соответствующий класс находится в файле `web/Request.php` в директории фреймворка.

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

## Компонент и объект ¶

В Yii 2.0 класс `CComponent` из версии 1.1 был разделён на два класса: yii\base\BaseObject и yii\base\Component. Класс BaseObject является простым базовым классом, который позволяет использовать геттеры и сеттеры для свойств. Класс Component наследуется от класса BaseObject и поддерживает события и поведения.

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

## Конфигурация объекта ¶

Класс BaseObject предоставляет единый способ конфигурирования объектов. Любой дочерний класс BaseObject может определить конструктор (если нужно) как показано ниже. Это позволит конфигурировать его универсально:

    class MyClass extends \yii\base\BaseObject
    {
        public function __construct($param1, $param2, $config = [])
        {
            // ... инициализация до того, как конфигурация будет применена

            parent::__construct($config);
        }

        public function init()
        {
            parent::init();

            // ... инициализация после того, как конфигурация была применена
        }
    }

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

Следуя этому соглашению, вы сможете создавать и конфигурировать новые объекты с помощью массива конфигурации:

    $object = Yii::createObject([
        'class' => 'MyClass',
        'property1' => 'abc',
        'property2' => 'cde',
    ], [$param1, $param2]);

Более подробная информация о конфигурации представлена в разделе «Настройки».

## События ¶

В Yii 1, события создавались с помощью объявления метода `on` (например, `onBeforeSave`). В Yii 2 вы можете использовать любое имя события. Вызывать события можно при помощи метода trigger().

    $event = new \yii\base\Event;
    $component->trigger($eventName, $event);

Для прикрепления обработчика события используйте метод on().

    $component->on($eventName, $handler);
    // убираем обработчик
    // $component->off($eventName, $handler);

Есть и другие улучшения по части событий, подробно описанные в разделе «События».

## Псевдонимы пути ¶

В Yii 2.0 псевдонимы используются более широко и применяются как к путям в файловой системе, так и к URL. Теперь, для того, чтобы отличать псевдонимы от обычных путей и URL, требуется, чтобы имя псевдонима начиналось с символа `@`. Например, псевдоним `@yii` соответствует директории, в которую установлен Yii. Псевдонимы пути используются во многих местах. Например, значение свойства yii\caching\FileCache::$cachePath может быть как псевдонимом пути так и обычным путём к папке.

Псевдонимы пути тесно связаны с пространством имён классов. Рекомендуется определять псевдоним пути для каждого корневого пространства имён, что позволяет использовать загрузчик классов Yii без какой-либо дополнительной настройки. Например, так как `@yii` соответствует директории, в которую установлен фреймворк, класс `yii\web\Request` может быть загружен автоматически. Если вы используете сторонние библиотеки, например, из Zend Framework, вы можете определить псевдоним пути `@Zend` как директорию, в которую установлен этот фреймворк. После этого Yii будет способен автоматически загружать любой класс Zend Framework.

Подробнее о псевдонимах пути можно узнать из раздела «Псевдонимы пути».

## Представления ¶

Одним из основных изменений в Yii 2 является то, что специальная переменная `$this` в представлении, больше не соответствует текущему контроллеру или виджету. Вместо этого, `$this` теперь соответствует объекту представления, новой возможности введённой в версии 2.0. Объект представления имеет тип yii\web\View, который представляет собой часть view в шаблоне проектирования MVC. Если вы хотите получить доступ к контроллеру или виджету, используйте выражение `$this->context`.

Для рендеринга частичных представлений теперь используется метод `$this->render()`, а не `$this->renderPartial()`. Результат вызова метода `render` теперь должен быть выведен напрямую, так как `render` возвращает результат рендеринга, а не отображает его сразу:

    echo $this->render('_item', ['item' => $item]);

Кроме использования PHP в качестве основного шаблонизатора, Yii 2.0 также предоставляет официальные расширения для двух популярных шаблонизаторов: Smarty и Twig. Шаблонизатор Prado больше не поддерживается. Для использования данных шаблонизаторов необходимо настроить компонент приложения `view` задав свойство View::$renderers. Подробнее об этом можно прочитать в разделе «Шаблонизаторы».

## Модели ¶

Yii 2.0 использует в качестве базового класса для моделей yii\base\Model, аналогичный классу `CModel` в версии 1.1. Класс `CFormModel` удалён. Вместо него для создания модели формы в Yii 2.0 вы должны напрямую наследоваться от yii\base\Model.

Появился новый метод scenarios() для объявления поддерживаемых сценариев, и для обозначения в каком сценарии атрибуты должны проверяться, считаться безопасными и т.п. Например,

    public function scenarios()
    {
        return [
            'backend' => ['email', 'role'],
            'frontend' => ['email', '!role'],
        ];
    }

В примере выше, объявлено два сценария: `backend` и `frontend`. Для `backend` сценария, оба атрибута `email` и `role` являются безопасными, и могут быть массово присвоены. Для сценария `frontend`, атрибут `email` может быть массово присвоен, а атрибут `role` нет. Оба атрибута `email` и `role` должны быть проверены с помощью правил валидации.

Метод rules() по-прежнему используется для объявления правил валидации. Обратите внимание, что в связи с появлением нового метода scenarios(), больше не поддерживается валидатор `unsafe`.

В большинстве случаев вам не нужно переопределять метод scenarios(), если метод rules() полностью указывает все существующие сценарии, и если нет надобности в объявлении атрибутов небезопасными.

Более детальная информация представлена в разделе «Модели».

## Контроллеры ¶

В качестве базового класса для контроллеров в Yii 2.0 используется yii\web\Controller, аналогичный `CController` в Yii 1.1. Базовым классом для всех действий является yii\base\Action.

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

    public function actionView($id)
    {
        $model = \app\models\Post::findOne($id);
        if ($model) {
            return $this->render('view', ['model' => $model]);
        } else {
            throw new \yii\web\NotFoundHttpException;
        }
    }

Более детальная информация представлена в разделе «Контроллеры».

## Виджеты ¶

В Yii 2.0 класс yii\base\Widget используется в качестве базового класса для виджетов, аналогично `CWidget` в Yii 1.1.

Для лучшей поддержки фреймворка в IDE, Yii 2.0 использует новый синтаксис для виджетов. Новые статические методы begin(), end(), и widget() используются следующим образом:

    use yii\widgets\Menu;
    use yii\widgets\ActiveForm;

    // Обратите внимание что вы должны выводить результат
    echo Menu::widget(['items' => $items]);

    // Указываем массив для конфигурации свойств объекта
    $form = ActiveForm::begin([
        'options' => ['class' => 'form-horizontal'],
        'fieldConfig' => ['inputOptions' => ['class' => 'input-xlarge']],
    ]);
    ... поляляя::end();

Более детальная информация представлена в разделе «Виджеты».

## Темы ¶

В Yii 2.0 темы работают совершенно по-другому. Теперь они основаны на механизме сопоставления путей исходного файла представления с темизированным файлом. Например, если используется сопоставление путей `['/web/views' => '/web/themes/basic']`, то темизированная версия файла представления `/web/views/site/index.php` будет находиться в `/web/themes/basic/site/index.php`. По этой причине темы могут быть применены к любому файлу представления, даже к представлению, отрендеренному внутри контекста контроллера или виджета. Также, больше не существует компонента `CThemeManager`. Вместо этого, `theme` является конфигурируемым свойством компонента приложения `view`.

Более детальная информация представлена в разделе «Темизация».

## Консольные приложения ¶

Консольные приложения теперь организованы как контроллеры, аналогично веб приложениям. Консольные контроллеры должны быть унаследованы от класса yii\console\Controller, аналогичного `CConsoleCommand` в версии 1.1.

Для выполнения консольной команды, используйте `yii <маршрут>`, где `<маршрут>` это маршрут контроллера (например, `sitemap/index`). Дополнительные анонимные аргументы будут переданы в качестве параметров соответствующему действию контроллера, в то время как именованные аргументы будут переданы в соответствие с объявлениями в yii\console\Controller::options().

Yii 2.0 поддерживает автоматическую генерацию справочной информации из блоков комментариев.

Более детальная информация представлена в разделе «Консольные команды».

## I18N ¶

В Yii 2.0 встроенные форматтеры времени и чисел были убраны в пользу PECL расширения PHP intl.

Перевод сообщений теперь осуществляется через компонент приложения `i18n`. Данный компонент управляет множеством исходных хранилищ сообщений, что позволяет вам использовать разные хранилища для исходных сообщений в зависимости от категории сообщения.

Более детальная информация представлена в разделе «Интернационализация».

## Фильтры действий ¶

Фильтры действий теперь сделаны с помощью поведений. Для определения нового фильтра, унаследуйтесь от yii\base\ActionFilter. Для использования фильтра, прикрепите его к контроллеру в качестве поведения. Например, для использования фильтра yii\filters\AccessControl, следует сделать следующее:

    public function behaviors()
    {
        return [
            'access' => [
                'class' => 'yii\filters\AccessControl',
                'rules' => [
                    ['allow' => true, 'actions' => ['admin'], 'roles' => ['@']],
                ],
            ],
        ];
    }

Более детальная информация представлена в разделе «Фильтры».

## Ресурсы ¶

В Yii 2.0 представлена новая возможность связка ресурсов, которая заменяет концепт пакетов скриптов в Yii 1.1.

Связка ресурсов — это коллекция файлов ресурсов (например, JavaScript файлы, CSS файлы, файлы изображений, и т.п.) в определенной директории. Каждая связка ресурсов представлена классом, унаследованным от yii\web\AssetBundle. Связка ресурсов становится доступной через веб после её регистрации методом yii\web\AssetBundle::register(). В отличие от Yii 1.1, страница, регистрирующая связку ресурсов, автоматически будет содержать ссылки на JavaScript и CSS файлы, указанные в связке.

Более детальная информация представлена в разделе «Ресурсы».

## Хелперы ¶

В Yii 2.0 включено много широко используемых статичных классов.

- yii\helpers\Html
- yii\helpers\ArrayHelper
- yii\helpers\StringHelper
- yii\helpers\FileHelper
- yii\helpers\Json

Более детальная информация представлена в разделе «Хелперы».

## Формы ¶

Yii 2.0 вводит новое понятие поле для построения форм с помощью yii\widgets\ActiveForm. Поле — это контейнер, содержащий подпись, поле ввода, сообщение об ошибке и/или вспомогательный текст. Поле представлено объектом ActiveField. Используя поля, вы можете строить формы гораздо проще чем это было раньше:

    <?php $form = yii\widgets\ActiveForm::begin(); ?>
        <?= $form->field($model, 'username') ?>
        <?= $form->field($model, 'password')->passwordInput() ?>
        <div class="form-group">
            <?= Html::submitButton('Login') ?>
        </div>
    <?php yii\widgets\ActiveForm::end(); ?>

Более детальная информация представлена в разделе «Работа с формами».

## Построитель запросов ¶

В версии 1.1, построение запроса было разбросано среди нескольких классов, включая `CDbCommand`, `CDbCriteria`, и `CDbCommandBuilder`. В Yii 2.0 запрос к БД представлен в рамках объекта Query, который может быть превращён в SQL выражение с помощью QueryBuilder. Например,

    $query = new \yii\db\Query();
    $query->select('id, name')
          ->from('user')
          ->limit(10);

    $command = $query->createCommand();
    $sql = $command->sql;
    $rows = $command->queryAll();

Лучшим способом использования данных методов является работа с Active Record.

Более детальная информация представлена в разделе «Построитель запросов».

## Active Record ¶

В Yii 2.0 внесено множество изменений в работу Active Record. Два основных из них включают в себя построение запросов и работу со связями.

Класс `CDbCriteria` версии 1.1 был заменен yii\db\ActiveQuery. Этот класс наследуется от yii\db\Query и таким образом получает все методы, необходимые для построения запроса. Чтобы начать строить запрос, следует вызвать метод yii\db\ActiveRecord::find():

    // Получаем всех *активных* клиентов и сортируем их по ID
    $customers = Customer::find()
        ->where(['status' => $active])
        ->orderBy('id')
        ->all();

Для объявления связи следует просто объявить геттер, который возвращает объект ActiveQuery. Имя свойства, определённое геттером, представляет собой название связи. Например, следующий код объявляет связь `orders` (в версии 1.1, вам нужно было бы объявить связи в одном месте — методе `relations()`):

    class Customer extends \yii\db\ActiveRecord
    {
        public function getOrders()
        {
            return $this->hasMany('Order', ['customer_id' => 'id']);
        }
    }

Теперь вы можете использовать выражение `$customer->orders` для получения всех заказов клиента из связанной таблицы. Вы также можете использовать следующий код, чтобы применить нужные условия «на лету»:

    $orders = $customer->getOrders()->andWhere('status=1')->all();

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

Вместо того, чтобы при выборке большого количества записей возвращать объекты ActiveRecord, вы можете использовать в построении запроса метод asArray(). Это заставит вернуть результат запроса в виде массива, что при большом количестве записей может существенно снизить затрачиваемое процессорное время и объём потребляемой памяти. Например:

    $customers = Customer::find()->asArray()->all();

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

    public function init()
    {
        parent::init();
        $this->status = self::STATUS_NEW;
    }

Также в версии 1.1 были некоторые проблемы с переопределением конструктора ActiveRecord. Данные проблемы отсутствуют в версии 2.0. Обратите внимание, что при добавлении параметров в конструктор, вам, возможно, понадобится переопределить метод yii\db\ActiveRecord::instantiate().

Существует также множество других улучшений в ActiveRecord. Подробнее о них можно узнать в разделе «Active Record».

## Поведения Active Record ¶

В версии 2.0 отсутствует базовый класс для поведений `CActiveRecordBehavior`. Если вам необходимо создать поведение для Active Record, стоит наследовать его класс напрямую от `yii\base\Behavior`. Если поведение должно реагировать на какие-либо события, необходимо перекрыть метод `events()` следующим образом:

    namespace app\components;

    use yii\db\ActiveRecord;
    use yii\base\Behavior;

    class MyBehavior extends Behavior
    {
        // ...

        public function events()
        {
            return [
                ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
            ];
        }

        public function beforeValidate($event)
        {
            // ...
        }
    }

## User и IdentityInterface ¶

Класс `CWebUser` из версии 1.1 теперь заменён классом yii\web\User. Также больше не существует класса `CUserIdentity`. Вы должны реализовать интерфейс yii\web\IdentityInterface, что гораздо проще. Пример реализации представлен в шаблоне приложения advanced.

Более подробная информация представлена в разделах «Аутентификация», «Авторизация» и «Шаблон приложения advanced».

## Разбор и генерация URL ¶

Работа с URL в Yii 2.0 аналогична той, что была в версии 1.1. Основное изменение заключается в том, что теперь поддерживаются дополнительные параметры. Например, если у вас имеется правило, объявленное следующим образом, то оно совпадет с `post/popular` и `post/1/popular`. В версии 1.1, вам пришлось бы использовать два правила, для достижения того же результата.

    [
        'pattern' => 'post/<page:\d+>/<tag>',
        'route' => 'post/index',
        'defaults' => ['page' => 1],
    ]

Более детальная информация представлена в разделе «Разбор и генерация URL».

## Использование Yii 1.1 вместе с 2.x ¶

Информация об использовании кода для Yii 1.1 вместе с Yii 2.0 представлена в разделе «Одновременное использование Yii 1.1 и 2.0».