Правила для urlManager

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
x86-cRash
Сообщения: 3
Зарегистрирован: 2011.12.28, 13:52

Правила для urlManager

Сообщение x86-cRash »

В "Руководстве" о правилах для urlManager сказано следующее: "При использовании createUrl для генерации адреса URL, маршрут и GET-параметры, переданные методу, используются для определения правила, которое нужно применить. Правило применяется в том случае, когда все параметры, ассоциированные с правилом, присутствуют среди GET-параметров, а маршрут соответствует параметру маршрута."
У меня есть такие правила для urlManager:

Код: Выделить всё

// ...
'urlManager' => array (
    'urlFormat' => 'path',
    'showScriptName' => FALSE,
    'rules' => array (
        'catalog' => 'catalog/lots',
        'catalog/<page:\d+>' => 'catalog/lots',
        'catalog/categories' => 'catalog/categories',
        'catalog/categories/<page:\d+>' => 'catalog/categories',
        'catalog/category/<category:\d+>' => 'catalog/lots',
        'catalog/category/<category:\d+>/<page:\d+>' => 'catalog/lots',
        'catalog/category/<category:\d+>/brand/<brand:\d+>' => 'catalog/lots',
        'catalog/category/<category:\d+>/brand/<brand:\d+>/<page:\d+>' => 'catalog/lots',
        'catalog/brands' => 'catalog/brands',
        'catalog/brands/<page:\d+>' => 'catalog/brands',
        'catalog/brand/<brand:\d+>' => 'catalog/lots',
        'catalog/brand/<brand:\d+>/<page:\d+>' => 'catalog/lots',
        'catalog/lot/<lot_id:\d+>' => 'catalog/lot'
    )
)
// ...
 
И createUrl, несмотря на то, что переданный набор параметров

Код: Выделить всё

echo $this->controller->createUrl('catalog/lots', array('category' => 2, 'brand' => 23, 'page' => 3)); 
однозначно соотвествует шаблону "catalog/category/<category:\d+>/brand/<brand:\d+>/<page:\d+>", возвращает адрес такого вида: "/catalog?category=2&brand=23&page=3". Поэкспериментировав с комментированием отдельных правил, которые находятся выше нужного, я понял, что createUrl берёт первый подходящий для контроллера/действия шаблон, игнорируя переданные параметры.
Исходя из этого, попробовал отсортировать массив правил по количеству параметров по убыванию:

Код: Выделить всё

// ...
'urlManager' => array(
    'urlFormat' => 'path',
    'showScriptName' => FALSE,
    'rules' => array(
        'catalog/category/<category:\d+>/brand/<brand:\d+>/<page:\d+>' => 'catalog/lots',
        'catalog/category/<category:\d+>/brand/<brand:\d+>' => 'catalog/lots',
        'catalog/category/<category:\d+>/<page:\d+>' => 'catalog/lots',
        'catalog/category/<category:\d+>' => 'catalog/lots',
        'catalog/brand/<brand:\d+>/<page:\d+>' => 'catalog/lots',
        'catalog/brand/<brand:\d+>' => 'catalog/lots',
        'catalog/<page:\d+>' => 'catalog/lots',
        'catalog' => 'catalog/lots',
        'catalog/brands' => 'catalog/brands',
        'catalog/brands/<page:\d+>' => 'catalog/brands',
        'catalog/lot/<lot_id:\d+>' => 'catalog/lot'
    )
)
// ...
 
И это помогло! Теперь метод createUrl возвращает нужный мне адрес.
А теперь суть вопроса. Что это? Ошибка моей версии Yii? В русской документации неверно описана работа с urlManager? Или в ней забыли описать какой-нибудь параметр, который заставил бы createUrl учитывать переданные параметры при поиске нужного шаблона?
Jampire
Сообщения: 207
Зарегистрирован: 2011.01.28, 11:45
Откуда: Гомель
Контактная информация:

Re: Правила для urlManager

Сообщение Jampire »

Если же количество GET-параметров больше, чем требует правило, то лишние параметры будут включены в строку запроса. Например, если вызвать $this->createUrl('post/read',array('id'=>100,'year'=>2008)), мы получим /index.php/post/100?year=2008. Для того, чтобы лишние параметры были отражены в информационной части пути, необходимо добавить к правилу /*. Таким образом, используя правило post/<id:\d+>/* получим URL вида /index.php/post/100/year/2008.
Путь вашего url в точности соответствует пути в первом правиле 'catalog' => 'catalog/lots'. Поэтому все остальные GET параметры считаются лишними и просто прикрепляются к строке запроса. Вывод, самое общее правило размещать в конце.
Изображение
Человек, говорящий, что это невозможно сделать, не должен мешать тому, кто это делает.
TM123
Сообщения: 608
Зарегистрирован: 2011.06.09, 11:18

Re: Правила для urlManager

Сообщение TM123 »

Нет, это такая логика работы, перебор вариантов идет до тех пор, пока не будет найден подходящий, по другому просто нельзя. Если под то что вы задали подпадает несколько правил, как программно определить какой из вариантов более правильный и соответственно какой использовать.
Задавая последовательность обработки вы тем самым указываете какой вариант правильный и исходя из этого частные правила идут в начале, общие в конце.
x86-cRash
Сообщения: 3
Зарегистрирован: 2011.12.28, 13:52

Re: Правила для urlManager

Сообщение x86-cRash »

Спасибо за ответы. С логикой работы метода я разобрался сразу же.
TM123 писал(а):...по другому просто нельзя.
Ну, позволю себе не согласиться с Вами, потому что в программировании нет ничего невозможного. В данном конкретном случае, всё зависит от того алгоритма, который ищет нужное правило, ведь в нём можно было бы учитывать количество переданных параметров. Другое дело, что разработчики решили сделать именно так.
Jampire писал(а):Вывод, самое общее правило размещать в конце.
Значит, как я и предполагал, в русском руководстве не совсем точно описана работа с urlManager. Обычно в руководствах акцентируют внимание на таких деталях. Иначе новички в том деле, которому посвящено руководство, могут запутаться. Как видите, я и сам запутался. Подумал, что метод createUrl сопоставляет не правила маршрутизации с переданными этому методу параметрами и берёт первое подходящее, а переданные параметры с правилами маршрутизации и использует то, которое полностью соответствует им или больше всего подходит. Немного грешу и на путанный язык перевода, за который справедливо критикуют русское руководство. А может, само оригинальное руководство так написано.
Jampire
Сообщения: 207
Зарегистрирован: 2011.01.28, 11:45
Откуда: Гомель
Контактная информация:

Re: Правила для urlManager

Сообщение Jampire »

x86-cRash писал(а):Ну, позволю себе не согласиться с Вами, потому что в программировании нет ничего невозможного. В данном конкретном случае, всё зависит от того алгоритма, который ищет нужное правило, ведь в нём можно было бы учитывать количество переданных параметров. Другое дело, что разработчики решили сделать именно так.
Именно так и сделано в самом программировании. Например, в исключениях самый общий catch ставится самым последним. В руководстве ясно сказано, что сопоставляются не параметры запроса, а непосредственно сам путь. Собственно дальше можно уже самому догадаться, что если самое общее правило стоит самым первым, то оно и сработает.
Изображение
Человек, говорящий, что это невозможно сделать, не должен мешать тому, кто это делает.
raketa
Сообщения: 131
Зарегистрирован: 2011.07.28, 17:29

Re: Правила для urlManager

Сообщение raketa »

меня тоже смущает выражение из русской документации
Правило применяется в том случае, когда все параметры, ассоциированные с правилом, присутствуют среди GET-параметров, а маршрут соответствует параметру маршрута.
...
и вопрос в тему
есть правило для статистических страниц

Код: Выделить всё

'<pname:[-_a-z]+>'=>'site/rules', 
не могу понять каким образом оно влияет на контроллер users, а именно перестают работать ссылки вида http:://site/users/ которые по сути должны вести к http:://site/users/index/
если вводить http:://site/users/index/ то все нормально

в rules правил к контроллеру users нет вообще, если закомментировать

Код: Выделить всё

'<pname:[-_a-z]+>'=>'site/rules', 
то все оk
я вообще не понимаю как это связано между собой
Ответить