Маршрутизатор CakePHP: подключаюсь, я не понимаю синтаксис

#cakephp #syntax #routes #router

#cakephp #синтаксис #маршруты #маршрутизатор

Вопрос:

Я пытаюсь подключить следующие URL-адреса:

1) /food/tips
2) /happiness/tips/best_tips

К следующим объектам:
1) controller=tips / action=index / passed_parameters=food
2) controller=tips / action=index / passed_parameters=(happiness,best_tips)

—редактировать —
Эти маршруты не исправлены.
Значение: то, что я пытаюсь сделать, это перенаправить каждый URL-адрес, который имеет tips значение action, на контроллер tips, на любое фиксированное (индекс достаточно хорош) действие и связать остальную часть URL-адреса, как это было в исходном вызове. Что-то вроде /any_controller/tips/any_param для /tips/index/any_params
— окончательная правка —

Надеюсь, что теперь в этом есть какой-то смысл.

Как это должно быть сделано? (пожалуйста — также объясните)

Спасибо

Ответ №1:

вся маршрутизация выполняется через вызов Router::connect(‘что нужно перехватить’, ‘куда это отправить’);

так что это может быть так просто, как:

 Router::connect('/food/tips', '/tips/index/food');
  

или предпочтительный метод (с использованием cakes, встроенных в url Builder)

 Router::connect('/food/tips/*', array('controller' => 'tips', 'action' => 'index', 'food');
  

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

Второй метод использует cakes, встроенный в формирователь URL, который принимает массив с ключами controller и action (есть другие варианты:http://api.cakephp.org/class/router#method-Routerurl ) Второй вариант предпочтительнее из-за правильного форматирования и будущей гибкости (я полагаю).

любые переданные параметры во втором методе просто передаются как безымянные элементы в массиве. именованные параметры просто передаются как элементы с ключом. Итак, если бы я хотел создать URL, подобный этому

/сообщения/индекс/найти:все/страница:2

Я бы написал URL следующим образом:

 Router::connect('/url_to_catch', array('controller' => 'posts', 'action' => 'index', 'find' => 'all', 'page' => 2);
  

Итак, чтобы закончить, я бы на самом деле передал ваш параметр как named:

 Router::connect('/happiness/tips/best_tips', array('controller' => 'tips', 'action' => 'index', 'items' => array('happiness', 'best_tips'));
  

для чего в вашем контроллере tips потребовалась бы функция, которая выглядит следующим образом:

 function tips(){ $this->passedArgs['items']; }
  

Ответ №2:

Я бы рекомендовал прочитать главу о маршрутизации в книге, поскольку она объяснит все лучше, чем я могу, и кажется контрпродуктивным вставлять ее сюда.

http://book.cakephp.org /#!/view/948/Определение-Маршрутов

Ради объяснения я попытаюсь,

 Router::connect('/food/tips', array('controller' => 'tips', 'action' => 'index', 'food'));
Router::connect('/happiness/tips/best_tips', array('controller' => 'tips', 'action' => 'index', 'happiness','best_tips'));
  

Это должно заставить вас работать. По сути, вы сообщаете маршрутизации Cake, какой URL-адрес вы хотите, чтобы он захватил, поскольку он будет делать это с использованием регулярных выражений. Затем вы хотите сообщить ему, какой код вы хотите, чтобы он запускался. Итак, для этого требуется пара контроллер и действие, как набор действий, которые нужно сделать.

Вы также хотите впоследствии пройти через свои именованные параметры. Они будут привязаны к функции в вашем контроллере, чтобы вы могли что-то с ними делать.

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

1. Спасибо @DavidYell, как я и писал @vindia, я отредактирую вопрос.

2. Да, я думаю, то, чего вы пытаетесь достичь, плохо. Очень плохо с точки зрения пирога. Тебе будет сложно. Я предлагаю Search стек для этого.

3. @DavidYell — search стек? Значение?

4. Я бы создал пустую модель, затем создал Search контроллер и использовал действие index, чтобы перенаправлять людей туда, куда они направлялись. Это не идеально, но дало бы вам больше гибкости и позволило бы разместить ваш код в одной точке приложения. Таким образом, по сути, люди могли искать подсказки по чему угодно и всегда оказывались в нужном месте. (Если я правильно понимаю ваши требования к функциональности!)

5. Возможно, но я больше хотел сказать, что это ошибка не вашего кода, а вашего программного дизайна.

Ответ №3:

Это довольно просто, просто проверьте конфигурацию маршрутизатора в руководстве. Вы должны использовать connect метод из Router класса. Это принимает 2 параметра. Сначала ваш желаемый маршрут (например food/tips ), а затем массив с фактическим путем, по которому он должен следовать. Итак, для ваших примеров вы бы сделали что-то вроде этого:

 Router::connect('/food/tips', array('controller' => 'tips', 'action' => 'index', 'food');
Router::connect('/happiness/tips/best_tips', array('controller' => 'tips', 'action' => 'index', 'happiness', 'best_tips');
  

Это эквивалентно вызову TipsController->index('food') и TipsController('happiness', 'best_tips) соответственно.

Однако ваши маршруты выглядят немного забавно. Соглашение Cake для маршрутов — это то, /controller/action/param1/param2/etc что параметры param1 и т.д. Являются необязательными, а index действие предполагается, когда никаких других действий не указано.

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

Итак, мое предложение касается tips/food и tips/happiness/best_tips вместо предлагаемых вами маршрутов. Таким образом, вам не нужно выполнять какую-либо настройку маршрутизатора.

Обновить

После редактирования, я думаю, лучше попробовать что-нибудь с определением пользовательских маршрутов. В данный момент я не могу протестировать это для вас, поэтому вам следует провести некоторое тестирование самостоятельно, но в этом случае это было бы что-то вроде:

 Router::connect('/:section/tips/:param', 
    array('action' => 'index'), 
    array(
        'section' => '[a-z]*', 
        'param' => '[a-z]*'
    )
);
  

UPDATE2

Извините, я тестировал выше, и, похоже, это не работает.

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

1. Ах, ты опередил меня в этом! Наверное, я печатаю медленно 😉

2. Спасибо @vindia, хотя это не решает мою проблему (моя ошибка, я отредактирую исходный вопрос) Что касается соглашений, моя проблема в том, что у меня есть контроллер tips, но нет раздела tips.. поэтому мне нужно направить каждый из них section/tips на контроллер tips…

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