@cmx

Как оформить правила маршрутизации при одиночном контроллере в Yii?

Есть один контроллер, у которого есть 3 action-a.
Как настроить правила маршрутизации так, чтобы не нужно было передавать значение контроллера (либо если значение не передается, то использовать default)?
Используемый urlFormat: get.
Перепробовал много вариантов, но ничего не работает. Видимо, я что-то не понимаю. На чем остановился:
'urlManager'=>array(
	'urlFormat'=>'get',
	'routeVar' => 'action',
	'rules' => array(
		'<action>' => 'site/<action>',
	),
),

Финальный url, который я тестирую выглядит так:
http://example.com/?action=index
  • Вопрос задан
  • 2918 просмотров
Решения вопроса 1
Creamov
@Creamov
Senior Fullstack Software Engineer
В Yii 1 (как во втором — не знаю), имя контроллера и имя действия передаётся одним GET параметром «r» (сокращение от route). При этом, имя действия можно не указывать. Но имя контроллера должно быть обязательно.

Если вы ставите urlFormat = path, то Yii будет парсить URL и будет использовать «rules».
Если вы ставите urlFormat = get, то Yii, просто перестаёт парсить URL и устанавливать «rules» бесполезно.

По умолчанию, вроде, вызывается DefaultController. Изменить это можно в конфиге:
return array(
    'defaultController' => 'site',   // По умолчанию будет использоваться SiteController
    // ...
);

В контролере должно быть действие по умолчанию actionIndex(), либо его можно переназначить так:
class DefaultController extends CController 
{
    public $defaultAction = 'my';

    public function actionMy() // Будет вызван по умолчанию
    {
          // делаем что-то
    }
}

Вы можете поступить так (urlFormat по умолчанию = path, менять routeVar не надо):
'urlManager' => array(
    'showScriptName' => false,
    'rules' => array( 
        '' => '<controller>/<action>', // Будет использоваться контроллер и действие по умолчанию
    ),
),

А в контроллере что-нибудь вроде этого:
class DefaultController extends CController 
{
    public function init()
    {
          parent::init();

          if ($action = Yii::app()->request->getParam('action', null)) 
          {
              $action = 'action' . ucfirst($action);

              if (in_array($action, get_class_methods(__CLASS__))) {
                  call_user_func(array(get_class(), $action)); // Вызываем действие
              }
          }
    }

    public function actionIndex() // Будет вызван по умолчанию
    {
        // делаем что-то
    }

    public function actionSimple()
    {
        // делаем что-то
    }
}

Обращаться можно так: site.ru/?action=simple. Также будет работать site.ru/simple
Создавать ссылки можно так: Yii::app()->createUrl('/', array('action' => 'simple'));

Вообще, метод init(), можно вынести в отдельный класс (например с именем AppContoller), который будет наследовать CController, а рабочий контроллер (с действиями) наследовать уже от него.

P.S писал в слепую, мог где-то ошибиться
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы