На днях вышел релиз 1.1.7 PHP-фреймворка Yii, в который было включено более 90 исправленных ошибок, улучшений и новых возможностей.
Полный список изменений доступен на сайте фреймворка, самые вкусные из которых мы рассмотрим ниже.
Поддержка URL в стиле REST
Теперь при использовании CUrlManager можно указать
метод (GET, POST, PUT и т.д.) в свойстве verb
правила URL.
К примеру, приведённые ниже правила GET
-запрос на post/123
будет обрабатываться
действием post/view
, а PUT
или POST
на post/123
— действием post/update
.
[php]
return array(
'components'=>array(
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
array('<controller>/view', 'pattern'=>'<controller:\w>/<id:\d+>', 'verb'=>'GET'),
array('<controller>/update', 'pattern'=>'<controller:\w>/<id:\d+>', 'verb'=>'PUT, POST'),
),
),
),
);
Получить данные PUT
и DELETE
можно при помощи методов CHttpRequest::getPut() и CHttpRequest::getDelete().
Кэширование запросов
При кэшировании запроса его результат сохраняется в кэш и, в случае повторного запроса берётся оттуда напрямую.
Кэширование запросов реализовано как для DAO, так и для AR. Несколько примеров:
[php]
// кэшируем результат выполнения $sql на 1000 секунд или пока не обновится tbl_post
$sql = 'SELECT * FROM tbl_post LIMIT 20';
$dependency = new CDbCacheDependency('SELECT MAX(update_time) FROM tbl_post');
$rows = Yii::app()->db->cache(1000, $dependency)->createCommand($sql)->queryAll();
// то же, но для AR
$posts = Post::model()->cache(1000, $dependency)->findAll();
// query caching with relational AR
$posts = Post::model()->cache(1000, $dependency)->with('author')->findAll();
Привязка параметров для классов действий
В версии 1.1.4 была добавлена поддержка автоматического наполнения параметров для действий контроллера. В этой версии возможность была расширена на действия, описываемые в классах. Пример:
[php]
class UpdateAction extends CAction
{
public function run($id)
{
// $id будет заполняться данными из $_GET['id']
}
}
Прозрачная валидация на клиенте
CActiveForm — мощный виджет, который значительно облегчает создание формы и её валидацию. Раньше он поддерживал только валидацию на стороне сервера и валидацию через AJAX. В данной версии добавлена валидация силами клиента, которая работает быстрее и не нагружает сервер.
Для реализации валидации на клиенте нет необходимости в дополнительном коде. Валидация работает на основе правил модели точно так же, как и валидация на стороне сервера.
Включить валидацию на клиенте можно выставив CActiveForm::enableClientValidation
в true
:
[php]
<?php $form=$this->beginWidget('CActiveForm', array(
'enableClientValidation'=>true,
)); ?>
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username'); ?>
<?php echo $form->error($model,'username'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password'); ?>
<?php echo $form->error($model,'password'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Login'); ?>
</div>
<?php $this->endWidget(); ?>
Передача параметров реляционным именованным группам параметров
Теперь можно передавать параметры реляционным именованным группам параметров. К примеру,
если имеется группа rated
в модели Post
, которая принимает параметром минимальный рейтинг записи,
можно использовать это из модели User
следующим образом:
[php]
$users=User::model()->findAll(array(
'with'=>array(
'posts'=>array(
'scopes'=>array(
'rated'=>5,
),
),
),
));
Использование 'through' с HAS_MANY и HAS_ONE
В Active Record добавлена поддержка опции through
, которая позволяет строить отношения,
подобные MANY_MANY
, но более гибкие, позволяющие получение и использование данных из
средней таблицы-моста.
К примеру, можно получить все комментарии для всех пользователей определённой группы.
Больше информации и примеров можно найти в соответствующем разделе руководства.
Использование транзакций в миграциях
При выполнении миграции бывают ситуации, когда часть миграции не применяется и требуется откатить всё, что успело примениться. Хорошее решение данной проблемы — обернуть всю миграцию в транзакцию. Конечно, можно сделать это и напрямую, но использование новой возможности более удобно.
Вместо реализации CDbMigration::up() и CDbMigration::down(), можно использовать CDbMigration::safeUp() и CDbMigration::safeDown(). После этого код будет обёрнут в транзакцию:
[php]
class m101129_185401_create_news_table extends CDbMigration
{
public function safeUp()
{
$this->createTable('tbl_news', array(
'id' => 'pk',
'title' => 'string NOT NULL',
'content' => 'text',
));
}
public function safeDown()
{
$this->dropTable('tbl_news');
}
}
Стоит отметить, что не все СУБД поддерживают транзакции.
Регистрация и использование своих пакетов скриптов
CClientScript теперь позволяет зарегистрировать и использовать свои пакеты скриптов. Ранее данная возможность использовалась исключительно для внутренних целей.
Пакет может содержать CSS, JavaScript, изображения и любые другие файлы, которые необходимо показать пользователям. Пакет может зависеть от других пакетов. То есть при регистрации пакета все пакеты, от которых он зависит, регистрируются автоматически.
Работа с пакетами строится следующим образом: сначала в CClientScript::packages описываются нужные пакеты, а затем они регистрируются при помощи CClientScript::registerPackage().