<rmcreative>

RSS

Свои классы для правил роутера Yii

24 мая 2011

В следующей версии Yii появится возможность использовать свой класс для конкретного правила роутера:

array(
  // стандартное правило CUrlRule
  '<action:(login|logout)>' => 'site/<action>',
 
  // свой класс
  array(
    'class' => 'application.components.MyUrlRule',
    'connectionID' => 'db',
  ),
)

Это позволит, например, с лёгкостью реализовать такую штуку, как наличие потенциально конфликтующих URL:

/about
/contact
/my-cool-blog-post
/my-cool-static-page

Код уже в транке, если есть желание или необходимость — можете опробовать. Замечания и предложения приветствуются.

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

  1. №4733
    xtsidx
    xtsidx 24 мая 2011 г., 22:29:26

    о да, круто. этого то мне и не хватало. Приходилось выкручиваться строгими правилами именования. спасибо.

  2. №4734
    Konstantin
    Konstantin 24 мая 2011 г., 23:03:11

    Хорошая вещь, надо забирать из транка.

  3. №4735
    Johnatan
    Johnatan 25 мая 2011 г., 0:04:09

    Как насчёт скорости? Ведь правила не слишком быстрые из-за регулярок, а с классом должны быть быстрее? А как на практике?

  4. №4736
    Sam
    Sam 25 мая 2011 г., 0:09:22

    Практики пока особо не было. Если есть время — можете сравнить.

  5. №4737
    Максим
    Максим 25 мая 2011 г., 17:19:27

    Клевая фича, теперь можно будет легко роуты из бд брать.

  6. №4741
    Евген
    Евген 27 мая 2011 г., 4:56:00

    Сможете привести пример использования своего класса где роут берется из БД?

  7. №4742
    Максим
    Максим 27 мая 2011 г., 11:39:22

    Код привожупримерный, чтоб была понятна идея

    class MyUrlRule extends CUrlRule {
    public $connectionId='db';
    // находим такой маршрут в бд и направляем на нужный route
    public mixed parseUrl(CUrlManager $manager, CHttpRequest $request, string $pathInfo, string $rawPathInfo)
    {
    // находим в бд
    $url=Route::model()->find($pathInfo);
    if(!isset($url))
    return false;
    foreach($url->params as $k=>$v)
    $_GET[$k]=$v;
    return $url->route;
    }
    // Вызывается для преобразования route в нормальный seo вид
    public mixed createUrl(CUrlManager $manager, string $route, array $params, string $ampersand)
    {
    // тут проверки что это наш route
    // если наш, то возвращаем его
    // если нет, то возвращаем false
    }
    }

    Думаю идея понятна. Детальней пока не могу описать.

  8. №4776
    Александр
    Александр 01 июня 2011 г., 10:34:37

    из последнего примера, получается что при каждом переходе по УРЛ, будет обращение к БД для сверки УРЛ? а можно как то проще сделать, сохранять правила в отдельный файл и его когда нужно подключать для проверки.

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

  9. №4779
    Timlar
    Timlar 01 июня 2011 г., 11:43:56

    А что мешает один раз забрать из базы правила и закешировать в тоем же мемкеше или редисе?

  10. №4785
    Александр
    Александр 01 июня 2011 г., 14:23:21

    ну тоже вариант, удобно, но с одной стороны, а вот если система модульная, и в базе хранить правила думаю совсем не удобно, проще с файлов собирать данные. Модуль просто кидается в соответствуюю модульную директорию, и от туда обработчик автоматически забирает правила(после можно и кэш примерить), а то нужно дополнительно писать для импорта правил в базу данных. Да и через файлы удобнее править, для базы нужно интерфейс реализовывать.

  11. №4786
    Sam
    Sam 01 июня 2011 г., 17:05:27

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

  12. №4793
    Александр
    Александр 02 июня 2011 г., 20:03:11

    Sam, да всё верно, надо просто вникнуть и разобраться, это я так с лёту, с глупыми вопросами. Единственное хотел попросить если ни кого не затруднит, подсказать что прописать у функции createUrl из выше приведённого кода, что и с чем нужно сравнить, и что подставить в качестве успешного результата, переменную/функцию. То что в случаи ложности нужно прописать return false я понял. А так всё понятно.

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

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

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