<rmcreative>

RSS

Yii 1.1.8

27 июня 2011

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

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

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

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

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

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

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 и выглядит примерно так:

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:

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

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

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

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

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

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

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

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

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

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

$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 // определяем 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',
))?>

Анонс на хабре

Комментарии RSS

  1. №4869
    OZ
    OZ 27 июня 2011 г., 0:33:53
    Yii::$enableIncludePath = false;

    И это в 2011 году, когда уже всё, что нужно, сказали Matt Zandstra, Martin Fowler и, особенно, Miško Hevery (статический класс, да ещё и с public-полем - сложно представить его реакцию).

    Мне в своём коде стыдно видеть такое, но вот они сделали обновление - значит эта фича не является наследием прошлого, могли ведь сделать метод, как минимум.

  2. №4870
    AmdY
    AmdY 27 июня 2011 г., 5:15:05
    Post::model()->updateCounters(array('views'=>1), 'id=1');

    зря вы так, можно сделать красиво и гибко

    $model->update(array('views'=>new DbExpresion('views+1')), 'id=1')
    $model->update(array('create_at'=>new DbExpresion('NOW()')), 'id=1')

    c renderClip так же странное решение, раз уж в Yii юзается eval, то стоило бы выделенный кусок евалить, тогда давая возможность пользоваться всеми возможностями шаблонизатора, а не плейсхолдеры. как, например, организовать там цикл?

  3. №4871
    Максим
    Максим 27 июня 2011 г., 12:29:33

    +1 про клипы.

  4. №4873
    idle
    idle 27 июня 2011 г., 15:15:15

    @OZ

    Мне в своём коде стыдно видеть такое...

    Истинно: каждый раз, когда Фаулер видит подобное, он дёргает волосы на своей голове и в остервенении начинает звать в свою церковь новую паству ещё громче.

  5. №4874
    Porcelanos
    Porcelanos 27 июня 2011 г., 16:17:20

    @OZ Ну а что тут такого страшного?

  6. №4876
    Sam
    Sam 27 июня 2011 г., 21:00:40

    OZ, предлагаете везде делать академично и без антипаттернов? Что тогда станет с синтаксисом?

    idle, посмотрел ещё раз на фото Фаулера :)

    AmdY, красиво и гибко тоже работает. Если есть цикл — скорее всего это тянет на полноценный view partial, но можно подумать и над полноценным PHP через output buffering.

  7. №4882
    Porter
    Porter 29 июня 2011 г., 0:27:57

    А тегированный кэш не добавили.. я в печали :(

  8. №4885
    Sam
    Sam 29 июня 2011 г., 3:54:19

    А разве планировали?

  9. №4888
    Andrey Gayvoronsky
    Andrey Gayvoronsky 29 июня 2011 г., 16:45:17

    Не могу понять это баг или нет?!

    http://www.yiiframework.com/forum/index.php?/topic/21032-activerecord-relations-cdbcriteria-behaviour/

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

  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.