Здравствуйте, уважаемые хабрапользователи!
Как вы уже поняли из заголовка, в данной статье пойдёт речь о новой версии Yii. Я попробую коротко, на живом примере, познакомить вас с замечательным Yii 2.
Писать полную инструкцию по созданию блога, наверное, не имеет смысла, так как многие шаги схожи с первой версией, но я буду писать именно про те нюансы, которые отличаются, и буду делать акцент на новинках Yii2, которые я заметил в процессе создания приложения. Всё же остальное вы сможете быстро посмотреть в демо приложении, что, наверное, будет более эффективно, чем просто написанный текст.
В Yii2, как вы уже заметили, все построено на namespace, это, пожалуй, основная «изюминка» в новой версии.
Также очень важный момент: «C» префикс из имён файлов был удалён.
За основу мы будем использовать basic приложение.
Как её установить очень хорошо описано на Github по этому сразу же переходим к следующим пунктам.
Для примера я выбрал модульную структуру. Это позволит нам узнать и понять принцип работы модулей в Yii2.
Итак, для того, чтобы реализовать такую структуру, нам, как и в первой версии, нужно создать основную папку всех модулей «modules», в которой мы уже будем создавать отдельные папки для отдельных модулей. Тут все, как в первой версии.
Единственное что поменялось в модулях – это название основного класса модуля. Как я понял, теперь уже не обязательно писать суффикс «Module», поэтому наши основные файлы будут иметь понятные имена без суффикса.
Пример:
Site.php, Users.php, Blogs.php, и.т.д.
Структуру вы сможете посмотреть уже на готовом примере, и останавливаться больше на этом не имеет смысла.
Как и в Yii 1.0, приложение настраивается через файла main.php, и многие элементы остались без изменений, но всё-таки есть много переименованных параметров, что следует помнить в случае неработоспособности приложения после конфигурации.
Несколько примеров таких изменений и особенностей:
В случае неработоспособности каких-либо параметров, можно легко подсмотреть все в исходниках фрейма.
Как только мы настроили наше приложение и подключили наши модули, можем приступить к написанию нашего «CRUD».
Подробный пример есть в демо коде, но, если честно, сильного отличия от первой версии нет. Единственное, что появилось новое, это ранее метод контроллера: populate(), который был перенесён на днях в модель и переименован в load().
Пример:
Других особых различий в работе с CRUD нет.
Основным нововведением является метод «scenarios() за счёт которого можно настроить валидаторы модели в зависимости от указанного сценария.
Привязка модели делается за счёт функции formName() которая в итоге возвращает имя Класса модели, к которой относится форма.
Также немаловажный момент — model() убрали, и теперь работа с моделью происходит, как и с другим обычным классом:
Тут все переписали, теперь в Yii2 новый AR, который реально радует.
Примеры нескольких нововведений:
«scopes()» были заменены на обычные методы AR модели, которые сейчас имеют такой вид:
Также радикально были изменены «relations()», которые сейчас задаются в виде гетерров, что более правильно. Доступны два типа relations: «hasOne()», «hasMany()».
Также были переписаны функции выборки из базы, и дополнены новыми.
И последнее, AR теперь делает автоматическую привязку модели к базе, за счёт функции «tableName()» которая по умолчанию возвращает такое значение «tbl_MODEL_NAME». Для примера, модель «User», будет привязана к таблице «tbl_user». Если же имя таблицы отличается, можно просто переопределить функцию.
В новой версии работать с событиями стало максимально просто. В демо приложении я привёл пример собственного события, — при добавлении нового пользователя, событие вызывается в afterSave(), хотя там можно использовать стандартные события, которые доступны в Yii, как например «EVENT_AFTER_INSERT».
Для того чтобы определить событие достаточно в нужном месте вызвать «trigger()» функцию, а уже потом в нужном месте задать для события обработчик.
Пример:
Есть несколько способов привязки обработчика:
В Yii2 появился новый класс, который отвечает за все представления приложения, и который выполняет непосредственно вывод информации.
Теперь в view файлах переменная "$this" относится уже не к контроллеру, а именно к новому классу «yii\base\View».
Д��я того, чтобы вызвать определённую функцию контроллера или виджета, к которому принадлежит представление, нужно обратится к методу: «context».
Пример:
Виджеты были дополнены новыми методами, плюс теперь они должны быть непосредственно выведены через «echo».
Пример:
В новой версии фильтры контроллеров реализованы в виде «behaviors».
Меленький нюанс — из коробки остались только 2 роли:
В Yii2 добавлены много новых хелперов. Например, как тот же SecurityHelper, который ускоряет работу с паролями и генерированными кодами, ArrayHelper, Html, и другие, что снова радует.
Формы теперь создаются ещё быстрее и удобнее, за счёт ActiveField класса, который упрощает стиль написания кода, что не может не радовать.
Робота с пользователями теперь осуществляется через класс «yii\web\User» и интерфейс «yii\web\Identity», что более гибко в использовании.
Из-за этих изменений атрибуты пользователя можно получить через метод «identity» пользователя.
Пример:
Тут чуток видоизменили стили записи правил.
Пример:
Работа с пользовательскими правами теперь доступна изначально из коробки без добавление своего кода, как, например, в случае с использованием файлового варианта в первой версии.
Ниже я напишу коротко инструкцию про RBAC и описание ролей в файле.
Для начала нам нужно создать свой класс, который будет наследоваться от "\yii\rbac\PhpManager".
В нашем примере он находится в модуле «rbac» в папке «components» под названием «PhpManager.php».
Код в нем простой. Мы просто задаём путь к нашему файлу с описанными ролями, и делаем привязку пользователя к нужной роли.
После, в той же папке мы создаём файл «rbac.php» где описываем нужные нам роли. (Код можно увидеть в демо приложении в папке:
Ну и, напоследок, нам осталось только настроить «authManager» в конфигурационном файле:
После чего в нужном нам месте мы можем смело делать проверки пользователя на наличие нужных прав:
Это все что я успел узнать, но, уверен, ещё есть много чего не успелось.
На данный момент я не успел разобраться с ajax запросами в Yii 2, а именно – как правильно создавать нужный ответ при валидации модели. В 1.0 это делается так:
если кто уже знает, пишите, уверен многим будет интересно.
Несмотря на ещё недоделанный вид, Yii 2 выглядит уже очень хорошо. Уверен, впереди нас ждёт только лучшее.
Самому Yii 2 очень понравился. Если честно, уже есть огромное желание начать писать рабочий проекты на новой версии, хотя до этого ещё очень рано.
Статья получилось большая, но по-другому просто не знаю как.
Спасибо всем за внимание. Удачи!
Демо блог на Github. Инструкция по установке присутствует.
Рабочий пример блога.
Как вы уже поняли из заголовка, в данной статье пойдёт речь о новой версии Yii. Я попробую коротко, на живом примере, познакомить вас с замечательным Yii 2.
Писать полную инструкцию по созданию блога, наверное, не имеет смысла, так как многие шаги схожи с первой версией, но я буду писать именно про те нюансы, которые отличаются, и буду делать акцент на новинках Yii2, которые я заметил в процессе создания приложения. Всё же остальное вы сможете быстро посмотреть в демо приложении, что, наверное, будет более эффективно, чем просто написанный текст.
Основные моменты
В Yii2, как вы уже заметили, все построено на namespace, это, пожалуй, основная «изюминка» в новой версии.
Также очень важный момент: «C» префикс из имён файлов был удалён.
Установка и создание первого приложения
За основу мы будем использовать basic приложение.
Как её установить очень хорошо описано на Github по этому сразу же переходим к следующим пунктам.
Структура приложения
Для примера я выбрал модульную структуру. Это позволит нам узнать и понять принцип работы модулей в Yii2.
Итак, для того, чтобы реализовать такую структуру, нам, как и в первой версии, нужно создать основную папку всех модулей «modules», в которой мы уже будем создавать отдельные папки для отдельных модулей. Тут все, как в первой версии.
Единственное что поменялось в модулях – это название основного класса модуля. Как я понял, теперь уже не обязательно писать суффикс «Module», поэтому наши основные файлы будут иметь понятные имена без суффикса.
Пример:
Site.php, Users.php, Blogs.php, и.т.д.
Структуру вы сможете посмотреть уже на готовом примере, и останавливаться больше на этом не имеет смысла.
Настройка приложения: config/main.php
Как и в Yii 1.0, приложение настраивается через файла main.php, и многие элементы остались без изменений, но всё-таки есть много переименованных параметров, что следует помнить в случае неработоспособности приложения после конфигурации.
Несколько примеров таких изменений и особенностей:
- Приркутка модулей теперь содержит обязательный параметр «class», который хранит имя основного класса модуля, и без которого подключить модуль не получится.
'modules' => array( ... 'users' => array( 'class' => 'app\modules\users\Users' ), ... ),
- Параметр «defaultController» убрали, и вместо него используется «defaultRoute».
- При настройке путей к директориям, можно использовать заданные алиасы "
@app, @www, @wwwroot", что очень удобно. - В UrlManager тоже переименовали несколько параметров. Теперь «urlFormat» заменили на «enablePrettyUrl», «useStrictParsing» на «enableStrictParsing».
- В компоненте «db» переименовали «connectionString» на «dsn».
В случае неработоспособности каких-либо параметров, можно легко подсмотреть все в исходниках фрейма.
Как только мы настроили наше приложение и подключили наши модули, можем приступить к написанию нашего «CRUD».
CRUD
Подробный пример есть в демо коде, но, если честно, сильного отличия от первой версии нет. Единственное, что появилось новое, это ранее метод контроллера: populate(), который был перенесён на днях в модель и переименован в load().
Пример:
public function actionCreate() { $model = new Blog(); if ($model->load($_POST) && $model->save()) { return Yii::$app->response->redirect(array('view', 'id' => $model->id)); } else { echo $this->render('create', array('model' => $model)); } }
$model->load($_POST) // тоже самое что if (isset($_POST['Blog'])) { $model->attributes = $_POST['Blog']; }
Других особых различий в работе с CRUD нет.
Модель
Основным нововведением является метод «scenarios() за счёт которого можно настроить валидаторы модели в зависимости от указанного сценария.
public function scenarios() { return array( 'backend' => array('email', 'role'), 'frontend' => array('email', '!name'), ); }
Привязка модели делается за счёт функции formName() которая в итоге возвращает имя Класса модели, к которой относится форма.
Также немаловажный момент — model() убрали, и теперь работа с моделью происходит, как и с другим обычным классом:
MyModel::getAuthor();
ActiveRecord
Тут все переписали, теперь в Yii2 новый AR, который реально радует.
Примеры нескольких нововведений:
«scopes()» были заменены на обычные методы AR модели, которые сейчас имеют такой вид:
public function active($query) { return $query->andWhere('status = ' . self::STATUS_ACTIVE); }
Также радикально были изменены «relations()», которые сейчас задаются в виде гетерров, что более правильно. Доступны два типа relations: «hasOne()», «hasMany()».
public function getAuthor() { return $this->hasOne('app\modules\users\models\User', array('id' => 'author_id')); // Первый параметр – это у нас имя класса, с которым мы настраиваем связь. // Во втором параметре в виде массива задаётся имя удалённого PK ключа (id) и FK из текущей таблицы модели (author_id), которые связываются между собой }
Также были переписаны функции выборки из базы, и дополнены новыми.
$customers = Customer::find() ->where(array('status' => $active)) ->orderBy('id') ->all(); // return the customer whose PK is 1 $customer = Customer::find(1); $customers = Customer::find(array('status'=>$active)); $customers = Customer::find()->asArray()->all(); $customers = Customer::find()->active()->asArray()->all();
И последнее, AR теперь делает автоматическую привязку модели к базе, за счёт функции «tableName()» которая по умолчанию возвращает такое значение «tbl_MODEL_NAME». Для примера, модель «User», будет привязана к таблице «tbl_user». Если же имя таблицы отличается, можно просто переопределить функцию.
События
В новой версии работать с событиями стало максимально просто. В демо приложении я привёл пример собственного события, — при добавлении нового пользователя, событие вызывается в afterSave(), хотя там можно использовать стандартные события, которые доступны в Yii, как например «EVENT_AFTER_INSERT».
Для того чтобы определить событие достаточно в нужном месте вызвать «trigger()» функцию, а уже потом в нужном месте задать для события обработчик.
Пример:
файл app\modules\users\models\User ... public function afterSave($insert) { // Создаём событие $event = new ModelEvent; $this->trigger(self::EVENT_NEW_USER, $event); parent::afterSave($insert); } ... файл app\modules\users\controllers\DefaultController ... public function actionSignup() { $model = new User(); $model->scenario = 'signup'; if ($model->load($_POST)) { if (!$this->module->activeAfterRegistration) // Задаём наш обработчик событий, для события [[EVENT_NEW_USER]] $model->on($model::EVENT_NEW_USER, array($this->module, 'onNewUser')); if ($model->save()) { Yii::$app->session->setFlash('success'); return Yii::$app->response->refresh(); } } else { echo $this->render('signup', array('model' => $model)); } } ...
Есть несколько способов привязки обработчика:
function ($event) { ... } // Анонимная функция array($object, 'handleClick') // $object->handleClick() array('Page', 'handleClick') // Page::handleClick() 'handleClick' // глобальная функция handleClick()
View
В Yii2 появился новый класс, который отвечает за все представления приложения, и который выполняет непосредственно вывод информации.
Теперь в view файлах переменная "$this" относится уже не к контроллеру, а именно к новому классу «yii\base\View».
Д��я того, чтобы вызвать определённую функцию контроллера или виджета, к которому принадлежит представление, нужно обратится к методу: «context».
Пример:
// Файл app\modules\blogs\views\default\index // $this->context относится к файлу app\modules\blogs\controllers\DefaultController // Простой вызов параметра модуля, к которому относится контроллер из представления echo $this->context->module->recordsPerPage; // Результат 10 //Файл app\modules\comments\widgets\comments\views\index // $this->context относится к файлу app\modules\comments\widgets\comments\Comments if ($this->context->model['id'] == 10 ) {...}
Widgets
Виджеты были дополнены новыми методами, плюс теперь они должны быть непосредственно выведены через «echo».
Пример:
// Note that you have to "echo" the result to display it echo \yii\widgets\Menu::widget(array('items' => $items)); // Passing an array to initialize the object properties $form = \yii\widgets\ActiveForm::begin(array( 'options' => array('class' => 'form-horizontal'), 'fieldConfig' => array('inputOptions' => array('class' => 'input-xlarge')), )); ... form inputs here ... \yii\widgets\ActiveForm::end();
Action Filters
В новой версии фильтры контроллеров реализованы в виде «behaviors».
public function behaviors() { return array( 'access' => array( 'class' => \yii\web\AccessControl::className(), 'rules' => array( // allow authenticated users array( 'allow' => true, 'actions' => array('login', 'signup', 'activation'), 'roles' => array('?') ), array( 'allow' => true, 'actions' => array('logout'), 'roles' => array('@') ), array( 'allow' => true, 'actions' => array('index', 'view'), 'roles' => array('guest') ), array( 'allow' => true, 'actions' => array('edit', 'delete'), 'roles' => array('@') ), // deny all - можно не писать, он по умолчанию всё запрещает array( 'allow' => false ) ) ) ); }
Меленький нюанс — из коробки остались только 2 роли:
- @ — авторизованные
- ? — гости
- * — была удалена.
Static Helpers
В Yii2 добавлены много новых хелперов. Например, как тот же SecurityHelper, который ускоряет работу с паролями и генерированными кодами, ArrayHelper, Html, и другие, что снова радует.
ActiveForm
Формы теперь создаются ещё быстрее и удобнее, за счёт ActiveField класса, который упрощает стиль написания кода, что не может не радовать.
<?php $form = ActiveForm::begin(array('options' => array('class' => 'form-horizontal'))); echo $form->field($model, 'username')->textInput($model->isNewRecord ? array() : array('readonly' => true)); echo $form->field($model, 'email')->textInput(); if (!$model->isNewRecord) { if (Yii::$app->user->checkAccess('editProfile')) { echo $form->field($model, 'status')->dropDownList(array( User::STATUS_ACTIVE => 'Active', User::STATUS_INACTIVE => 'Inactive', User::STATUS_DELETED => 'Deleted' )); echo $form->field($model, 'role')->dropDownList(array( User::ROLE_USER => 'User', User::ROLE_ADMIN => 'Admin' )); } echo $form->field($model, 'oldpassword')->passwordInput(); } echo $form->field($model, 'password')->passwordInput(); echo $form->field($model, 'repassword')->passwordInput(); ?> <div class="form-actions"> <?php echo Html::submitButton($model->isNewRecord ? 'Register' : 'Update', array('class' => 'btn btn-primary')); ?> </div> <?php ActiveForm::end(); ?>
User and Identity
Робота с пользователями теперь осуществляется через класс «yii\web\User» и интерфейс «yii\web\Identity», что более гибко в использовании.
Из-за этих изменений атрибуты пользователя можно получить через метод «identity» пользователя.
Пример:
echo Yii::$app->user->identity->username;
URL Management
Тут чуток видоизменили стили записи правил.
Пример:
... array( 'dashboard' => 'site/index', 'PUT post/<id:\d+>' => 'post/update', 'POST,PUT post/index' => 'post/create', 'POST <controller:\w+>s' => '<controller>/create', '<controller:\w+>s' => '<controller>/index', 'PUT <controller:\w+>/<id:\d+>' => '<controller>/update', 'DELETE <controller:\w+>/<id:\d+>' => '<controller>/delete', '<controller:\w+>/<id:\d+>' => '<controller>/view', ); ...
RBAC
Работа с пользовательскими правами теперь доступна изначально из коробки без добавление своего кода, как, например, в случае с использованием файлового варианта в первой версии.
Ниже я напишу коротко инструкцию про RBAC и описание ролей в файле.
Для начала нам нужно создать свой класс, который будет наследоваться от "\yii\rbac\PhpManager".
В нашем примере он находится в модуле «rbac» в папке «components» под названием «PhpManager.php».
Код в нем простой. Мы просто задаём путь к нашему файлу с описанными ролями, и делаем привязку пользователя к нужной роли.
<?php namespace app\modules\rbac\components; use Yii; class PhpManager extends \yii\rbac\PhpManager { public function init() { if ($this->authFile === NULL) $this->authFile = Yii::getAlias('@app/modules/rbac/components/rbac') . '.php'; parent::init(); if (!Yii::$app->user->isGuest) $this->assign(Yii::$app->user->identity->id, Yii::$app->user->identity->role); } }
После, в той же папке мы создаём файл «rbac.php» где описываем нужные нам роли. (Код можно увидеть в демо приложении в папке:
@app/modules/rbac/components/rbac)Ну и, напоследок, нам осталось только настроить «authManager» в конфигурационном файле:
... 'authManager' => array( 'class' => 'app\modules\rbac\components\PhpManager', 'defaultRoles' => array('guest'), ), ...
После чего в нужном нам месте мы можем смело делать проверки пользователя на наличие нужных прав:
if (Yii::$app->user->checkAccess('editOwnBlog', array('blog' => $model)) || Yii::$app->user->checkAccess('editBlog')) { ... }
Это все что я успел узнать, но, уверен, ещё есть много чего не успелось.
На данный момент я не успел разобраться с ajax запросами в Yii 2, а именно – как правильно создавать нужный ответ при валидации модели. В 1.0 это делается так:
echo CActiveForm::validate($model);
если кто уже знает, пишите, уверен многим будет интересно.
Итог
Несмотря на ещё недоделанный вид, Yii 2 выглядит уже очень хорошо. Уверен, впереди нас ждёт только лучшее.
Самому Yii 2 очень понравился. Если честно, уже есть огромное желание начать писать рабочий проекты на новой версии, хотя до этого ещё очень рано.
Статья получилось большая, но по-другому просто не знаю как.
Спасибо всем за внимание. Удачи!
Демо блог на Github. Инструкция по установке присутствует.
Рабочий пример блога.
