Введение
На днях, свершилось событие, которое Я и думаю еще немало людей ждали. Авторы 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/
Добавить комментарий