Обновление с версии 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. Таким образом, существует много различий в языке, которые вы должны принимать во внимание:

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

Одним из основных изменений в 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']],
]);
... поля формы ...
ActiveForm::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 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».