YiiConf 2017 всё ближе! Не забудьте купить билет.
Yii 1.1.8

Вышел релиз Yii 1.1.8, включающий более 80 багфиксов, новых возможностей и улучшений. Огромное спасибо тем, кто репортил баги, предлагал новые фичи и использовал по назначению Orphus на yiiframework.ru.

Забрать свежий дистрибутив можно с официального сайта.

Инструкции по обновлению можно почитать в UPGRADE.

Полный список изменений, как обычно, можно прочитать в CHANGELOG, мы же бегло рассмотрим самое интересное.

Свои классы для правил URL

Для сложной работы с URL, с которой не может справится стандартный класс CUrlRule (например, когда часть URL зависит от значений в базе данных), можно написать свои классы для обработки URL и использовать их в конфигурации CUrlManager:

[php]
array(
    // стандартное правило '/login' → 'site/login' и т.д.
    '<action:(login|logout|about)>' => 'site/<action>',
 
    // нестандартное правило для '/Производитель/Модель'
    array(
        'class' => 'application.components.CarUrlRule',
        'connectionID' => 'db',
    ),
 
    // стандартное правило для 'post/update'
    '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),

Сам класс при этом наследуется от CBaseUrlRule и выглядит примерно так:

[php]
class CarUrlRule extends CBaseUrlRule
{
    public $connectionID = 'db';
 
    public function createUrl($manager,$route,$params,$ampersand)
    {
        if ($route==='car/index')
        {
            if (isset($params['manufacturer'], $params['model']))
                return $params['manufacturer'] . '/' . $params['model'];
            else if (isset($params['manufacturer']))
                return $params['manufacturer'];
        }
        return false;  // не применяем правило
    }
 
    public function parseUrl($manager,$request,$pathInfo,$rawPathInfo)
    {
        if (preg_match('%^(\w+)(/(\w+))?$%', $pathInfo, $matches))
        {
            // совпадают ли $matches[1] и $matches[3] с
            // производителем и моделью в базе?
            // если да, выставляем $_GET['manufacturer'] и/или $_GET['model']
            // и возвращаем 'car/index'
        }
        return false;  // не применяем правило
    }
}

Улучшенный автозагрузчик классов

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

[php]
// По умолчанию сторонний загрузчик регистрируется до загрузчика Yii
Yii::registerAutoloader($autoloader);

Теперь можно делать так:

[php]
// При передаче true вторым параметром сторонний автозагрузчик добавляется после загрузчика Yii
Yii::registerAutoloader($autoloader, true);

По умолчанию автозагрузчик Yii использует PHP include path. Для некоторых хостингов это является проблемой, решить которую можно немного поправив index.php:

[php]
require('path/to/yii.php');
// отключаем PHP include path
Yii::$enableIncludePath = false;
Yii::createWebApplication($config)->run();

Логирование в режиме реального времени

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

[php]
// автоматически передаём каждое сообщение роутеру лога
Yii::getLogger()->autoFlush = 1;
// автоматически пишем сообщения при получении логгером
Yii::getLogger()->autoDump = true;

Работаем со счётчиками в БД через AR

В классе CActiveRecord появился новый метод saveCounters(), похожий на существующий CActiveRecord::updateCounters(). Главное отличие — saveCounters() работает только с текущим объектом в то время как updateCounters() работает со всей таблицей:

[php]
$post = Post::model()->findByPk(1);
// наращиваем количество просмотров поста
$post->saveCounters(array('views'=>1));
// то же для прошлый версий
Post::model()->updateCounters(array('views'=>1), 'id=1');

Генерация файлов переводов

При использовании yiic message часто приходилось удалять старый файл и заменять его новым, который генерировался рядом. Теперь можно писать сразу в старый файл, если выставить в конфигурации команды опцию overwrite в true.

Создание URL в консольных приложениях

В веб-приложениях для генерации URL обычно используется CUrlManager, который ранее не был доступен консольным приложениям. Теперь и в веб-приложениях и в консольных можно пользоваться Yii::app()->createUrl(), что очень удобно, например, для построения sitemap, в котором перечисляются URL веб-приложения.

В clips теперь можно использовать параметры

Это полезно в том случае, когда кусок кода в view повторяется много раз, но он недостаточно сложен для выноса его в отдельный файл:

[php]
<?php // определяем clip ?>
<?php $this->beginClip('hello')?>
<p>Привет, {username}!</p>
<?php $this->endClip() ?>
 
<?php // используем clip ?>
<?php $this->renderClip('hello',array(
    '{username}'=>'Qiang',
))?>
<?php $this->renderClip('hello',array(
    '{username}'=>'Alex',
))?>
<?php $this->renderClip('hello',array(
    '{username}'=>'Michael',
))?>