developer blog – 451 degrees Fahrenheit

Developer Blog

Новинки в symfony 1.2 или движемся к простой архитектуре (Часть 1)

September 5th, 2008 by pilot | 4 Комментария »

Сегодня мы поговорим о новой системе роутинга – роутинг фрейморк.

Роутинги как объекты класса

До symfony 1.2, система роутинга (через класс sfPatternRouting ) хранила роуты в ассоциативном массиве. Старая система отлично работает, но при этом трудно настраиваемая под свои нужды. Для того чтоб дать разработчикам свободу в модификации и улучшении процесса роутинга, в новой версии все роуты хранятся как массив объекта sfRoute.

Роутинг 1.2 совместим с 1.1 и не требует никаких дополнительных изменений в routing.yml файле.

Если вы хотите прописать роуты напрямую в PHP, теперь нужно указывать объект sfRoute вторым аргументов для методов connect(), preprendRoute(), appendRoute(), и insertRouteBefore() :

$routing->connect('foo_bar', new sfRoute('/foo/:bar', array('module' => 'foo', 'action' => 'bar')));

Настройка роута

Конструктор класса sfRoute принимает последним аргументом массив опций, который позволяет легко настраивать роуты. В конфигурационном файле routing.yml , ключ options применяется для замены настроек по умолчанию:

article:
  url:     /article/:id-:slug
  options: { segment_separators: [/, ., -] }  

В опции segment_separators  указываются символы разделители для роута. В предыдущем примере как разделитель  испольются - (дефис), которые в нашем случае так же валиден как и два разделителя встроенных по умолчанию (/ и .). Таких образом допускаются ссылки вида /article/1-my_article_title с переменной id равной 1 и slug равной my_article_title.

Эта опция уже доступна в symfony 1.1, но только глобально для всех роутов. Таким образов добавив глобальный разделитель, вы можете нарушить работу роутингов определенных в сторонних плагинах.

Кроме этого доступно еще две новых опции:

  • generate_shortest_url: генерация коротких URL, насколько это возможно 
  • extra_parameters_as_query_string: генерация дополнительных параметров в виде запроса

Эти опции могут быть заданы глобально либо отдельно для каждого роута. По умолчанию обе опции равны false в factories.yml для того чтоб сохранить совместимость с предыдущими версиями symfony.

Пример того как использовать эти опции для настроки роутов:

articles:
  url:     /articles/:page
  param:   { module: article, action: list, page: 1 }
  options: { generate_shortest_url: true }  

Этот роут генерит максимально короткий URL. Т.е. если запросить page равное 1, что является значением по умолчанию для переменной page, на выходе получим URL вида /articles:

echo url_for('@articles?page=1'); // generates /articles
// would have been /articles/1 in symfony 1.1   
echo url_for('@articles?page=2'); // generates /articles/2  

Другой пример, как работает опция extra_parameters_as_query_string:

articles:
  url:     /articles
  options: { extra_parameters_as_query_string: true }  

Такой роут принимает дополнительные параметры, которые не валидны для переменных заданных в патерне роута (в самом примере таких переменных как мы видим вообще нет):

echo url_for('@articles?page=1'); // generates /articles?page=1
// would not have matched the route in symfony 1.1
echo url_for('@articles?page=2'); // generates /articles?page=2  

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

Настройка роутингов

Вся логика из класса sfPatternRouting была перемещенна в объект sfRoute:

  • Когда пришел HTTP запрос, объект роутинга опрашивает каждый роут не совпадает ли он с зпрошеным URL.
  • И в момент когда вы хотети сгенерировать URL, объект роутинга опрашивает каждый роут на возможность сгенерировать URL по предоставленным параметрам.

Добавление всей логики в класс роутига, в этом случае не важно либо это создание нового класса роутинга для иземения направления парсинга роутов либо генерация всего процесса роутов.

Если вы хотите изменить класс обработки роутов используемый по умолчанию на свой, добавьте ключ class в файл конфигурации роутов:

article:
  url:   /article/:id
  param: { module: article, action: index }
  class: myRoute  

С такой конифгурацией ротинга, для обработки роута article symfony будет использовать класс myRoute, вместо стандартного класса sfRoute. И теперь роуты будут зависить от поведенния заданного в вашем классе.

Новый класс sfRoute намного модульнее чем старый sfPatternRouting, что позволяет легко настраивать стандартное поведение класса.

Стандартный sfRequestRoute

В Symfony есть стандартный класс роутинга, sfRequestRoute, который можно применять в ходе процесса сопостовления HTTP метода:

article:
  url:          /article/:id
  requirements: { sf_method: get }
  class:        sfRequestRoute  

В представленной конфигурации роутинга, роут article будет совпадать только запросу с HTTP методом GET.

Если вы хотите задать несколько роутов с одинаковым url, но с разными методами, вы можете добавить параметер  sf_method во время генерации роута:

<?php echo link_to('Great article', '@article?id=1&sf_method=get')) ?>  

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

  • method: HTTP метод
  • format: формат запроса 
  • host: имя хоста 
  • is_secure: был ли запрос вызван через HTTPS или нет 
  • request_uri: полный запрошеный URI  
  • prefix: префикс добавляемый к каждому сгенерированному запросу

В общем sfRequestRoute – это первый шаг на пути к простой архитектруре.

Что дальше?

В следующей части, мы познакомимся с тем как symfony управляет рессурсами при автоматической генерации роутов основанных на простой конфигурации файла routing.yml.

О новой системе роутинга будет доклад на symfonyCamp с большим количеством примеров и живим демо, так что все желающие пока еще не поздно регистрируйтесь.

Если вы хотите следить за процессом внедрения изменений в symfony 1.2 проверяйте переодически страницу upgrade to symfony 1.2 все новинки будут появлятся на ней в по ходу появляния.

top of hotblogs.org.ua

Раздел Symfony

4 Responses

  1. Новинки в symfony 1.2 или движемся к простой архитектуре (Часть 1) Says:

    [...] статьи на русском 451f.com.ua Теги: rout, routing [...]

  2. Карсонито Says:

    “О новой системе роутинга будет доклад на symfonyCamp с большим количеством примеров и живим демо, так что все желающие пока еще не поздно регистрируйтесь.”
    Пустите меня в Голландию!

  3. Dmitry Nesteruk Says:

    Очень интересная статья, надо будет и свой проект с symfony 1.1 перетащить на эту версию

  4. xandr Says:

    Еще вариант настройки Routing

    //routing.yml
    service_record:
    class: sfPropelRouteCollection
    options:
    model: ServiceRecord
    module: service_record
    prefix_path: service_record
    column: slug
    with_wildcard_routes: true
    model_methods:
    object: fetchBySlug
    requirements: { slug: “\d{2,4}-\d{2}-\d{2}_\d+_\d+” }

    Первичный ключ состоит из 3х столбцов, даты, часа и отдела.

    Колонки slug нету, реализован просто метод в объекте

    class ServiceRecord extends BaseServiceRecord
    {
    public function getSlug()
    {
    return $this->getDate().’_’.$this->getHour().’_’.$this->getDepartmentId();
    }
    }

    и метод в пире

    class ServiceRecordPeer extends BaseServiceRecordPeer
    {
    public static function fetchBySlug($parameters){
    $separ = explode(‘_’, $parameters['slug']);
    $c = new Criteria();
    $c->add(self::DATE, $separ[0]);
    $c->add(self::HOUR, $separ[1]);
    $c->add(self::DEPARTMENT_ID, $separ[2]);
    return self::doSelectOne($c);
    }
    }

    В админке все работает.

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.