Yii Framework 2 Release

  2015-11-25 11:38:57

Несколько дней назад был анонсирован public preview новой версии любимого мной фреймворка Yii 2.0, код выложен на github. Код фреймворка, подготавливался более двух лет в закрытом режиме. Сейчас он находится в стадии активных изменений, поэтому как следствие, те же авторы не рекомендуют его использовать в реальных проектах, но это не мешает нам с ним познакомится.

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

Кстати, чтобы хотя бы вкратце ознакомится с тем, что полноценно реализовано на данный момент или наблюдать за тем куда движется развитие можно, изучив Yii2 Development Roadmap.

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

Если говорить предельно кратко, то в новой версии фреймворка:

Отсутствие обратной совместимости с Yii 1.1;
Пересмотрена архитектура классов, некоторые их реализации;
Отсутствие, как следствие новой архитектуры, некоторых сущностей, например: CDbCriteria, CClientScript, CUserIdentity и другие;
Поддержка шаблонизаторов Smarty и Twig.

Namespace
Отныне и повсеместно Yii 2.0 использует пространства имен, и это не может не радовать, особенно в случаях, когда проект начинает разрастаться. Префикс «C» перестал использоваться в именах классов. Именование классов соответствует структуре папок фреймворка, например класс yii\web\Request говорит, о том что будет подключен файл web/Request.php в папке фреймворка. Кстати вложенность в большинстве случаев не больше двух, поэтому объявление класса вряд ли покажется огромным, более того его даже легко запомнить.

Да, как ты догадался, теперь фреймворк требует PHP 5.3 (или если быть точным PHP 5.3.8+) со многими вытекающими (но приятными) последствиями, например использование анонимных функций.

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

Также псевдонимы тесно связаны с пространством имен. Рекомендуется определять псевдоним для каждого корня пространства имен. Если ты используешь сторонние библиотеки, как например Zend Framework, то ты должен определить псевдоним @Zend, который будет ссылаться на директорию
куда установлен Zend, чтобы автозагрузчик классов Yii смог обработать любой класс оттуда, например:

\Yii::setAlias('@Zend', '@app/vendors/Zend');

Кстати упомянутый выше автозагрузчик классов Yii соответвует PSR-0.

Компонент и объект
Класс CComponent, положенный в основу любого компонента в Yii1.x, теперь представлен в виде двух сущностей:

\yii\base\Object - легковесный класс, реализующий определение атрибутов класса через методы получение (set) и установки (get);
\yii\base\Component - является расширением вышеуказанного, который поддерживает дополнительно события (event) и поведения (behavior).


По рекомендации авторов Yii, если проектируемый тобой класс не нуждается в использовании событий и поведений, наследуй его от Object.

Класс Object устанавливает общий подход для формирования объектов, где любой потомок класса должен объявлять конструктор в следующем порядке:

class MyClass extends \yii\base\Object
{
public function __construct($param1, $param2, $config = array())
{

// .. начальная инициализация перед назначением настроек
parent::__construct($config);
}

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

// ... инициализация перед назначением настроек
}
}

Последний параметр принимает массив будущих атрибутов класса. Согласно данному подходу создание и конфигурирование нового объекта/компонента будет выглядеть следующим образом:

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

События
Больше нет необходимости объявлять on-методы. Чтобы подписаться на событию необходимо:

$component->on($eventName, $handler);

Для того, чтобы отписаться необходимо:

$component->off($eventName, $handler);

Как видите все просто, к тому же имя события может быть каким угодно. В связи с этими изменениями, ты можешь использовать события «глобально», тоесть через обращение к Yii::$app, например:

Yii::$app->on($eventName, $handler);
// ..
// вызов события и как следствие запуск его обработчиков
Yii::$app->trigger($eventName);

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

Теперь когда в Yii 2.0 появился класс View, фреймворк полноценно реализует паттерн MVC. Конфигурирование представления происходит глобально через компонент view, который также доступен в некоторых файлах представления через переменную $this. Это одно из самых значительных изменений по сравнению с версией 1.1, поскольку раньше переменная $this ссылалась на контроллер или виджет. Сейчас, чтобы получить доступ к контроллеру или виджету используй $this->context внутри представления.

В представлениях изменился также ActiveForm, тут появилась концепция полей, которые включают в себя input, label и сообщение об ошибке, что делает код более аккуратным. В связи с глобальным доступом к компоненту view ты можешь рендерить представления в любой части своего приложения, необязательно в контролерах и виджетах.

До сих пор по умолчанию PHP остается основным шаблонизатором в Yii, но в новой версии фреймворка появилась встроенная поддержка шаблонизаторов
Smarty и Twig (Prado больше не поддерживается). Для использования других необходимо изменить свойство View::renderers.

Темы
Темы теперь работают полностью по другому, их работа основана на карте путей, которая транслируют файл представления в файл представления темы. Например, если карта путей представляет собой массив array('/www/views' => '/www/themes/basic'), то темизированная версия файла /www/views/site/index.php будет находится в /www/themes/basic/site/index.php.

В связи с этим тема может общаться к любым файлам представления, даже если они оказались вне контекста контроллера или виджета.

Класс CThemeManager теперь отсутствует, а чтобы изменить текущую тему достаточно изменить theme свойство компонента view.

Контроллеры
Вместо вывода результатов рендеринга напрямую методы render() и renderPartial() теперь возвращают результат исполнения, другими словами, чтобы что-нибудь вывести необходимо выполнить echo $this->render(…);

Появился метод populate() позволяющий с легкостью назначить атрибуты модели полученных от пользователя через запрос, например:

$model = new Post;
if ($this->populate($_POST, $model)) {...}Что полностью совпадает с:
if (isset($_POST['Post'])) {
$model->attributes = $_POST['Post'];
}

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

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

Модели
В классе модели \yii\base\Model появился метод formName(), возвращающий имя формы, что используется в первую очередь при создании HTML форм. Раньше в Yii 1.1, именем формы являлось имя класс модели.

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

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

Этот метод также определять какие атрибуты являются безопасными, а какие нет. В частности, если в списке атрибутов сценария попадается атрибут без префикса !, это означает что он безопасный. В выше приведенном примере атрибут name небезопасный, когда другие вполне. В связи с этими изменениями в Yii 2.0 теперь отсутствует валидаторы «safe» и «unsafe».

Построитель запросов.
Помнишь в Yii 1.1, чтобы построить запрос ты использовал несколько классов CDbCommand, CDbCriteria, и CDbCommandBuilder?

Сейчас в Yii 2.0 для этого используется класс Query, а для генерироования SQL класс QueryBuilder, напримеру:

$query = new \yii\db\Query;
$query->select('id, name')
->from('tbl_user')
->limit(10);
$command = $query->createCommand();
$sql = $command->sql;
$rows = $command->queryAll();

Лучше всего строить подобные запросы вместе с ActiveRecord

ActiveRecord
Класс ActiveRecord претерпел значительные изменения в Yii 2.0 Наиболее важным из них являются отношения (relations). Из всех реляций, которые были в Yii 1.1, остались только has_one и has_many.

В версии 1.1 ты должен был объявлять их в методе relations(), а в последней версии это делается с помощью get методов, которые возвращают
объект ActiveQuery. Например, следующий метод объявляет отношение «orders» для класса Customer (покупатель):

class Customer extends \yii\db\ActiveRecord
{

public function getOrders()
{
return $this->hasMany('Order', array('customer_id' => 'id'));
}
}

В данном примере ты можешь использовать $customer->orders для доступа к заказам покупателя, а чтобы выполнить запрос содержащий реляцию или какое-нибудь условие достаточно сделать нечто похожее на $customer->getOrders()->andWhere('status=1')->all(), выстроив цепочку методов.

Yii 2.0 больше не использует метод model() для выполнения запросов, взамен используй метод find(), например:

// извлечь всех "активных" покупателей и упорядочить их по ID:
$customers = Customer::find()
->where(array('status' => $active))
->orderBy('id')
->all();
// получить покупателя со значением первичного ключа равным 1
$customer = Customer::find(1);

Метод find() возвращает экземпляр ActiveQuery являющийся потомком Query,поэтому можешь смело использовать все методы из Query. вместо того чтобы ActiveRecord возвращал вам объекты ты можете вызывать ActiveQuery::asArray() чтобы получить результаты в виде массива, например:

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

В версии 1.1 при вызове save() в базу данных сохранялись все атрибуты, независимо от их изменялись они или нет, за исключением, если ты явно не перечислил атрибуты для сохранения, теперь в 2.0 по умолчанию ActiveRecord сохраняет только грязные (измененные) атрибуты.

Среди прочих изменений можно добавить, что методы primaryKey() и tableName() стали статическими методами.

Консольные приложения
Консольные приложения теперь также как и веб-приложения состоят из контроллеров и по сути оба наследуются от одного базового класса контроллера. Каждый консольный контроллер похож на класс CConsoleCommand из Yii 1.1 и состоит из одного или нескольких действий.

Чтобы выполнить консольную команду используй yiic , где это путь до контроллера (например, sitemap/index). Дополнительные анонимные аргументы передаются в качестве параметров для соответствующего метода контроллера, а именованные аргументы рассматриваются в качестве глобальных параметров, отъявленных в GlobalOptions().

Yii 2.0 поддерживает автоматическое создание справки из блока комментариев.

Yii 2.0 активно развивается Новая версия фреймворка очень заметно развивается, не только в плане исправления ошибок но и документации, достаточно проследить за активностью в течение нескольких дней:

3 мая, вышел Public preview Yii 2.0;

6 мая, Yii 2.0 на первом месте в github, по рейтингу и количеству созданных веток в этот день, неделю и месяц. Также в этот день появляется первое расширение nested-set-behavior-2 от creocoder. На Хабрахабр появляется статья "Создание простого CRUD-приложения с помощью Yii2";

7 мая, обновление гайдов на хитгаб, в том числе Upgrading from Yii 1.1;

8 мая, статья на Хабрахарб «Yii2. Знакомство».

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

По материалам сайта:

http://allframeworks.ru/post/obzor-yii-20.html