Yii Framework Forum: Очередность Правил Для Url - Yii Framework Forum

Jump to content

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

Очередность Правил Для Url непонятки с конфигом Rate Topic: -----

#1 User is offline   styleroom 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 337
  • Joined: 14-January 12
  • Location:Долгопрудный, Россия

Posted 08 November 2013 - 02:01 AM

всем привет

столкнулся с непонятной для меня ситуацией = движок реагирует на очередность расположения правил формирования URL при распознавании ключей GET-параметров...

то есть вот эти две очередности правил =
'/<sect:[a-z0-9\_\-]+>/<subsect:[a-z0-9\_\-]+>' => 'site/handler',
'/<sect:[a-z0-9\_\-]+>/<page:[a-z0-9\_\-]+>' => 'site/handler',

и
'/<sect:[a-z0-9\_\-]+>/<page:[a-z0-9\_\-]+>' => 'site/handler',
'/<sect:[a-z0-9\_\-]+>/<subsect:[a-z0-9\_\-]+>' => 'site/handler',

по разному трактуют второй ключ подаваемый в массиве для createUrl

в первом случае вторым ключем всегда будет subsect - даже если в createURL подать page
а во втором случае вторым ключем всегда будет page - даже если в createURL подать subsect

это так и должно быть или я туплю?

как проверял =
1) в методе контроллера сделал так =
print_r(Yii::app()->controller->actionParams)

2) в представлении создал рядом две ссылки =
<a href="<?php echo Yii::app()->createURL(
        'site/handler',array(
            'sect'=>$_GET['sect'],'subsect'=>'community',)); ?>">
    второй ключ = sect
</a>
<br>
<a href="<?php echo Yii::app()->createURL(
        'site/handler',array(
            'sect'=>$_GET['sect'],'page'=>'community',)); ?>">
    второй ключ = page
</a>


клики и по первой и по второй ссылке привели к отображению =
Array
(
    [sect] => character
    [page] => community
)


p.s. с другой стороны - если убрать правила для URL вообще - то все работает корректно (только все виде строки запроса - чего крайне не хотелось бы)
I'm sorry for my English...
0

#2 User is offline   andy_s 

  • Random Member Title
  • Yii
  • Group: Moderators
  • Posts: 1,526
  • Joined: 22-June 09
  • Location:Russia, Kostroma

Posted 08 November 2013 - 02:20 AM

Для subsect и page у вас одинаковые правила, поэтому, когда приходит url "aaa/bbb", то невозможно определить, что есть что.
0

#3 User is offline   styleroom 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 337
  • Joined: 14-January 12
  • Location:Долгопрудный, Россия

Posted 08 November 2013 - 02:28 AM

View Postandy_s, on 08 November 2013 - 02:20 AM, said:

Для subsect и page у вас одинаковые правила, поэтому, когда приходит url "aaa/bbb", то невозможно определить, что есть что.

а разве само изменение ключа - не является достаточным?
я так понимаю - раз ключ изменился = значит и формирование URL с его обработкой то же поменяется
разве это не так?

p.s. вам не трудно предложить свой вариант правил, которые бы все исправили как надо? ну хотя бы приблизительно

p.s.2 а то ведь получается что в правилах не имеет значение название ключа = важной оказывается только очередность ключей в УРЛ
I'm sorry for my English...
0

#4 User is offline   styleroom 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 337
  • Joined: 14-January 12
  • Location:Долгопрудный, Россия

Posted 08 November 2013 - 02:48 AM

перенаправил обработку УРЛ с ключем page на другой метод (метод есть в контроллере и абсолютно идентичен handler) =
'/<sect:[a-z0-9\_\-]+>/<subsect:[a-z0-9\_\-]+>' => 'site/handler',
'/<sect:[a-z0-9\_\-]+>/<page:[a-z0-9\_\-]+>' => 'site/handler2',

УРЛы сформировались так =
для subsect = /character/community.html
для page = /character.html?page=community

?????
теперь что не так?
I'm sorry for my English...
0

#5 User is offline   andy_s 

  • Random Member Title
  • Yii
  • Group: Moderators
  • Posts: 1,526
  • Joined: 22-June 09
  • Location:Russia, Kostroma

Posted 08 November 2013 - 03:21 AM

Одно дело сформировать url, другое дело - сопоставить готовому какое-то правило в rules. Процесс останавливается на первом подходящем правиле. Т.к. левые части абсолютно одинаковые, то при определении контроллера/экшена всегда будет срабатывать только первое правило. Неоднозначность можно устранить по-разному, например:

'/<sect:[a-z0-9\_\-]+>/page/<page:[a-z0-9\_\-]+>' => 'site/handler',
'/<sect:[a-z0-9\_\-]+>/sub/<subsect:[a-z0-9\_\-]+>' => 'site/handler',

0

#6 User is offline   styleroom 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 337
  • Joined: 14-January 12
  • Location:Долгопрудный, Россия

Posted 08 November 2013 - 03:45 AM

View Postandy_s, on 08 November 2013 - 03:21 AM, said:

Т.к. левые части абсолютно одинаковые

эва как...
почему-же они абсолютно одинаковые? в одном случае <subsect:[a-z0-9\_\-]+> а в другом <page:[a-z0-9\_\-]+>
по ключу-то они совершенно разные...
или парсер правил игнорирует subsect и page?

если не сложно - растолкуйте логику
I'm sorry for my English...
0

#7 User is offline   andy_s 

  • Random Member Title
  • Yii
  • Group: Moderators
  • Posts: 1,526
  • Joined: 22-June 09
  • Location:Russia, Kostroma

Posted 08 November 2013 - 03:56 AM

Логика на самом деле простая:

CHtml::link('Ссылка 1', array('site/handler', 'sect'=>'aaa', 'page'=>'bbb'));
CHtml::link('Ссылка 2', array('site/handler', 'sect'=>'aaa', 'subsect'=>'bbb'));


С вышеуказанными правилами создадутся ссылки, ведущие на один адрес "http://site.ru/aaa/bbb". Или не так? При разборе такого адреса подходит как первое правило, так и второе. Названия параметров роли не играют, просто соответствующим $_GET параметрам будут присвоены значения aaa и bbb.
0

#8 User is offline   styleroom 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 337
  • Joined: 14-January 12
  • Location:Долгопрудный, Россия

Posted 08 November 2013 - 04:05 AM

View Postandy_s, on 08 November 2013 - 03:56 AM, said:

Логика на самом деле простая:

CHtml::link('Ссылка 1', array('site/handler', 'sect'=>'aaa', 'page'=>'bbb'));
CHtml::link('Ссылка 2', array('site/handler', 'sect'=>'aaa', 'subsect'=>'bbb'));


С вышеуказанными правилами создадутся ссылки, ведущие на один адрес "http://site.ru/aaa/bbb". Или не так? При разборе такого адреса подходит как первое правило, так и второе. Названия параметров роли не играют, просто соответствующим $_GET параметрам будут присвоены значения aaa и bbb.

я в шоке = названия параметров роли не играют...
но ведь = просто соответствующим $_GET параметрам будут присвоены значения

так вот и вопрос - каким $_GET параметрам?
вторым по счету или ключам page и subsect?

в моем понимании какой ключ подан(subsect или page), такой же ключ и должен быть в УРЛ
а парсер разбирающий правила в конфиге должен учитывать ключи подаваемые в правилах
но по факту это не так = ибо = названия параметров роли не играют

фигня какая-то
p.s это не к вам
I'm sorry for my English...
0

#9 User is offline   andy_s 

  • Random Member Title
  • Yii
  • Group: Moderators
  • Posts: 1,526
  • Joined: 22-June 09
  • Location:Russia, Kostroma

Posted 08 November 2013 - 04:44 AM

Возможно, код вам лучше объяснит: http://www.yiiframew...parseUrl-detail :)

Суть в том, что Yii берёт URL, затем проходит по каждому правилу (левая часть rules) и делает preg_match (предварительно приведя эти левые части к корректному регулярному выражению). Проблема в том, что preg_match для обоих правил возвращает true (на самом деле процесс останавливается при первом совпадении), т.к. он не может знать, является ли часть "bbb" параметром page или subsect, ведь у них одинаковый паттерн ([a-z0-9\_\-]+).
0

#10 User is offline   styleroom 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 337
  • Joined: 14-January 12
  • Location:Долгопрудный, Россия

Posted 08 November 2013 - 04:50 AM

View Postandy_s, on 08 November 2013 - 04:44 AM, said:

Возможно, код вам лучше объяснит: http://www.yiiframew...parseUrl-detail :)

Суть в том, что Yii берёт URL, затем проходит по каждому правилу (левая часть rules) и делает preg_match (предварительно приведя эти левые части к корректному регулярному выражению). Проблема в том, что preg_match для обоих правил возвращает true (на самом деле процесс останавливается при первом совпадении), т.к. он не может знать, является ли часть "bbb" параметром page или subsect, ведь у них одинаковый паттерн ([a-z0-9\_\-]+).

да вы и без кода мне все в предыдущих постах все растолковали - я усе понял

мне только тогда не понятно = нафига в правилах заморачиваться на указание GET-ключей если они роли не играют?
ведь по сути роль играет очередность правил в левой части
GET-ключи тут вообще ни при чем... CodeIgniter какой-то получается :)

лох номер 1 в моем лице повелся именно на возможность манипулирования ключами в правилах и тут лоха постигла неудача

p.s. спасибо, что не поленились полезть в parseUrl
I'm sorry for my English...
0

#11 User is offline   andy_s 

  • Random Member Title
  • Yii
  • Group: Moderators
  • Posts: 1,526
  • Joined: 22-June 09
  • Location:Russia, Kostroma

Posted 08 November 2013 - 05:17 AM

Параметры играют роль при создании url, а при разборе помогают правильно присвоить значения $_GET['sect'], $_GET['page'] и т.п.
0

#12 User is offline   styleroom 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 337
  • Joined: 14-January 12
  • Location:Долгопрудный, Россия

Posted 08 November 2013 - 05:34 AM

View Postandy_s, on 08 November 2013 - 05:17 AM, said:

Параметры играют роль при создании url, а при разборе помогают правильно присвоить значения $_GET['sect'], $_GET['page'] и т.п.

да ни фига они не помогают если на уровне разбора правил из конфига не учитываются указанные ключи( по вашим же словам = Названия параметров роли не играют )

получается, что в моем случае невозможно два УРЛа преобразовать
из
/index.php?r=site/handler&sect=character&page=first-character-article
/index.php?r=site/handler&sect=media&subsect=photo

в
/character/first-character-article.html
/media/photo.html

с учетом того, что значения GET-ключей sect, subsect и page формируются динамически и не могут быть заранее прописаны в конфиге

p.s. вы сможете помочь написать мне такие правила?
I'm sorry for my English...
0

#13 User is offline   styleroom 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 337
  • Joined: 14-January 12
  • Location:Долгопрудный, Россия

Posted 08 November 2013 - 05:59 AM

вот так работает =
'/<sect:(character|community)>/<page:[a-z0-9\_\-]+>' => 'site/handler',
'/<sect:[a-z0-9\_\-]+>/<subsect:[a-z0-9\_\-]+>' => 'site/handler',

но приходится явно указывать значение ключа sect, а так быть не должно
I'm sorry for my English...
0

#14 User is offline   andy_s 

  • Random Member Title
  • Yii
  • Group: Moderators
  • Posts: 1,526
  • Joined: 22-June 09
  • Location:Russia, Kostroma

Posted 08 November 2013 - 06:00 AM

Конкретно в вашем случае не помогают, конечно, но если в rules нет таких неоднозначных правил, то помогают :)

Решить проблему можно по-разному:

1. Испортить красивые url и сделать их такими:
/character/page/first-character-article.html
/media/sect/photo.html

2. Если множество значений subsect заранее известно, то поставить это правило первым и перечислить значения в виде [value1|value2|...

3. Направлять всё в один контроллер, который уже будет сам "догадываться", page там или subsect (или сделать свой класс, наследующий CBaseUrlRule).
0

#15 User is offline   ORey 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,689
  • Joined: 20-April 09
  • Location:Moscow, Russia

Posted 08 November 2013 - 06:07 AM

View Poststyleroom, on 08 November 2013 - 04:05 AM, said:

в моем понимании какой ключ подан(subsect или page), такой же ключ и должен быть в УРЛ


Все вот эти приблуды - <key:[...]+> - это тупо именованный регэксп )
Не какие-то волшебные параметры или ключи, а всего-навсего поименованная область.

По вариантам решения andy_s уже кажется вообще всё возможное расписал )

UPD: вот еще полезная штука
God is real unless declared as integer
0

#16 User is offline   styleroom 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 337
  • Joined: 14-January 12
  • Location:Долгопрудный, Россия

Posted 08 November 2013 - 06:15 AM

View Postandy_s, on 08 November 2013 - 06:00 AM, said:

1. Испортить красивые url и сделать их такими:
/character/page/first-character-article.html
/media/sect/photo.html
не-не-не... УРЛ-ы это святое

View Postandy_s, on 08 November 2013 - 06:00 AM, said:

2. Если множество значений subsect заранее известно, то поставить это правило первым и перечислить значения в виде [value1|value2|...
это очевидно, но не хотелось бы

View Postandy_s, on 08 November 2013 - 06:00 AM, said:

3. Направлять всё в один контроллер, который уже будет сам "догадываться", page там или subsect
а поподробнее = ведь и сейчас все идет в один контроллер и в один метод
I'm sorry for my English...
0

#17 User is offline   andy_s 

  • Random Member Title
  • Yii
  • Group: Moderators
  • Posts: 1,526
  • Joined: 22-June 09
  • Location:Russia, Kostroma

Posted 08 November 2013 - 06:35 AM

View Poststyleroom, on 08 November 2013 - 06:15 AM, said:

а поподробнее = ведь и сейчас все идет в один контроллер и в один метод


Например, искать значения в базе данных. Если нашли статью first-character-article, значит это параметр page, в противном случае не page :) Хотя тут уже вам виднее. Можно вообще все url'ы хранить в таблице БД (url, controller/action).
0

#18 User is offline   styleroom 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 337
  • Joined: 14-January 12
  • Location:Долгопрудный, Россия

Posted 08 November 2013 - 06:46 AM

View Postandy_s, on 08 November 2013 - 06:35 AM, said:

Например, искать значения в базе данных. Если нашли статью first-character-article, значит это параметр page, в противном случае не page :) Хотя тут уже вам виднее. Можно вообще все url'ы хранить в таблице БД (url, controller/action).
тю! я-то думал...
ведь сейчас именно так и есть - все лежит в БД и по условию линк подставляется или в subsect или в page
только функция createURL все равно работает не до конца правильно (ну, в моем конечно понимании)

выше я даже написал о том как проверял - когда врукопашную указал второй ключ и его значение - все равно не помогло

видать никуда не деться от этого =
'/<sect:(character|community)>/<page:[a-z0-9\_\-]+>' => 'site/handler',
'/<sect:[a-z0-9\_\-]+>/<subsect:[a-z0-9\_\-]+>' => 'site/handler',

I'm sorry for my English...
0

#19 User is offline   andy_s 

  • Random Member Title
  • Yii
  • Group: Moderators
  • Posts: 1,526
  • Joined: 22-June 09
  • Location:Russia, Kostroma

Posted 08 November 2013 - 07:03 AM

http://www.yiiframew...82%D0%BE%D0%B4/

View Poststyleroom, on 01 November 2013 - 02:02 AM, said:

какие меня могут ожидать подводные камни и сложности?


Думаю, это ещё не последние сложности :)
0

#20 User is offline   samdark 

  • Having fun
  • Yii
  • Group: Yii Dev Team
  • Posts: 3,385
  • Joined: 17-January 09
  • Location:Russia

Posted 08 November 2013 - 04:17 PM

'test1/<param1>' => 'test/index',
'test2/<param2>' => 'test/index',


Тут левая часть у нас шаблон URL, правая — внутренний маршрут (он же роут).

Есть два разных действия: формирование URL и разбор URL.

1. При формировании мы передаём внутренний маршрут и набор параметров. Например, так:

echo $this->createUrl('test/index', array('param1' => 'paramOne')).'<br>';
echo $this->createUrl('test/index', array('param2' => 'paramTwo')).'<br>';


Yii проходит правила сверху вниз. Сначала смотрим, совпал ли внутренний маршрут из правой части. Далее, переданы ли все именованные параметры, перечисленные в левой части. Если да, используем правило. Если нет, смотрим следующее.

Пример выше выдаст нам:

/test1/paramOne
/test2/paramTwo


2. При разборе у нас есть URL. Например, /test/paramValue.

Если все правила достаточно уникальны, проблемы нет. Если же у нас:

'test/<param1>' => 'test/index',
'test/<param2>' => 'test/index',


То не ясно, какое из правил должно сработать т.к. в URL не указано, что такое это paramValue. Поэтому срабатывает первое попавшееся.
Yii 1.1 Application Development Cookbook

Enjoying Yii? Star us at github: 1.1 and 2.0.
0

Share this topic:


  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users