Yii2. Знакомство

от автора

Введение

На днях, свершилось событие, которое Я и думаю еще немало людей ждали. Авторы Yii Framework выкатили превью-версию.

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

Начало

Вторая версия отличается от первой кардинально. Список в краткой форме:

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

— Базовый CComponent разделили на Object и Component. Первый осуществляет работу геттеров и сеттеров, второй расширяя первый, добавляя события и поведения.

-Видоизменилось подключение событий и поведений. Подписываемся на событие

$post->on('update', function($event) {     // send email notification }); 

Настраиваем компонент

$component = \Yii::createObject(array(   'class' => '\app\components\GoogleMap',   'apiKey' => 'xyz',   // Добавим событие   'on eventName' => array('Event', 'run'),   // Добавим поведение   'as behaviorName' => array(/* Behavior config */), )); 

— Добавили новый класс View, теперь у нас настоящий MVC фреймворк. Представление

<?php use yii\helpers\base\Html; /**  * Обратите внимание $this в представлении это уже не контроллер.  * Добраться к контроллеру можно $this->context  * @var yii\base\View $this  */ $this->title = 'Hello world'; ?> <h1><?php echo Html::encode($this->title); ?></h1> <p class="lead">Привет мир!</p> 

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

— Действие контроллера больше ничего не выводит. Оно возвращает данные

public function actionIndex() { 	echo $this->render('index'); } 

— В контроллере появились два события, на котрые можно подписываться: beforeAction, afterAction

public function init() {   $this->on('beforeAction', function($event) {     // отменяем действие     $event->isValid = false;   }); } 

— Убраны фильтры контроллера CFilter, теперь все делается через поведения

public function behaviors() {   return array(     'AccessControl' => array(       'class' => '\yii\web\AccessControl',       'rules' =>array(/* тут ничего не поменялось */),     ),   ); } 

— В контроллере появился отличный помощник — метод populate

public function actionLogin() {   $model = new LoginForm();   if ($this->populate($_POST, $model) && $model->login()) {     Yii::$app->response->redirect(array('site/index'));   }    echo $this->render('login', array(     'model' => $model,   )); } 

— Добавлены еще несколько статических классов-хелперов: ArrayHelper, StringHelper, SecurityHelper. Все хелперы теперь можно перекрыть через LSB. Ура, воскликнул я, т.к лично мне не раз нужно было перекрыть Html.

— Виджет ActiveForm тоже переписан, и скорее всего заменит форм-билдер CForm. Каждое поле формы теперь может быть представлено как объект ActiveField, который создает ActiveForm

$form = $this->beginWidget('yii\widgets\ActiveForm', array(   'options' => array('class' => 'form-horizontal') ));    echo $form->field($model, 'username')->textInput();    echo $form->field($model, 'password')->passwordInput();    echo $form->field($model, 'rememberMe')->checkbox();    echo Html::tag('div', Html::submitButton('Login', null, null, array('class' => 'btn btn-primary')), array(     'class' => 'form-actions'    ));  $this->endWidget(); 

* Внимание: в Html::tag($tag, $content, $options) — изменили порядок параметров!

ActiveRecord

«По большей части, ActiveRecord осталась нетронутой»

— написано в предыдущей статье. Верно подмечено — не трогали.
Просто взяли и написали совсем другой ActiveRecord.

— Забываем про model()

— Убран CDbCriteria. Но не пугайтесь, работа с базой стала от этого легче. Появился ActiveQuery, который представляет себя гибрид CActiveFinder и CDbCriteria.

// получаем экземпляр ActiveQuery $query = Post::find();  // все посты $posts = $query->all();  // ищем все посты с условием $posts = $query     ->where(array('status' => Post::DRAFT))     ->orderBy('time')     ->all();  // ищем один пост  $post = $query    ->where(array('id' => 10, 'status' => Post::READ))    ->one();  // или проще, условие where можно передавать прямо в фабричный метод $post = Post::find(array('id' => 10, 'status' => Post::READ));  // передав в фабричный метод не массив а число эквивалентно поиску по первичному ключу  $post = Post::find(10)    ->where(array('status' => Post::READ))    ->one();  // индексируем результат по нужному атрибуту $posts = $query->indexBy('title')->all();  // результат в виде массива $posts = $query->asArray()->all(); 

— Все общие методы теперь статические: getDb, tableName, find*, save*, primaryKey. Выигрыш очевиден.

— Связи, куда же без них. Теперь связи определяются добавлением геттеров

class Post extends ActiveRecord {     public function getCreator()     {         return $this->hasOne('User', array('id' => 'user_id'));     }     public function getComments()     {         return $this->hasMany('Comment', array('post_id' => 'id'));     }     public function getTrustComments($isTrust = true)     {         return $this->hasMany('Comment', array('post_id' => 'id'))             ->where('status = :status', array(                      ':status' => $isTrust ? self::TRUST : self::UNTRUST,               ))             ->orderBy('id');     } } 

— Для удобства работы со связями добавили link() и unlunk(), который автоматически расставят ключи

$post = Post::find(1);  $comment = new Comment(); $comment->text = 'Yii Framework is cool!'; $post->link('comments', $comment); 

— Именованные группы условий есть, но в другом виде. У нас же нет больше CDbCriteria, а значит и массивов условий тоже больше нет. Теперь это методы, причем статические, добавляющие условия в Query

class Post extends \yii\db\ActiveRecord {     /**      * @param ActiveQuery $query      */     public static function byCreator($query, $userId)     {         $query->andWhere('user_id = :userId', array('userId' => $userId));     }     /**      * @param ActiveQuery $query      */     public static function removed($query)     {         $query->andWhere('removed = 1');     } }  $posts = Post::find()->removed()->all(); $myPosts = Post::find()->byCreator(Yii::$app->user->id)->all(); 

Все

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

До связи.

ссылка на оригинал статьи http://habrahabr.ru/post/178917/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *