Задать вопрос

Как вызвать контроллер из другого контроллера?

Исторически сложилось что в web приложении существует несколько контроллеров, типа:
pages
products

и дефолтовые правила роутинга для них /

Заказчик изьявил желание сделать все ссылки SEO-friendly в виде /page1.html, /product-cool.html (то есть без указаний контроллера).
Очевидным решением проблемы мог бы быть .htaccess но его «завернули» словами никаких редиректов. :(

Второе что приходит в голову — сделать некую таблицу соответствий виртуального адреса и настоящего контроллера, экшена и параметров. После этого зароутить все запросы на этот единственный «роутер2»

поковырявшись в документации так и не нашел — можно ли в yii в одном контроллере вызывать другой и отобразить его результат работы?
  • Вопрос задан
  • 17921 просмотр
Подписаться 9 Оценить Комментировать
Решения вопроса 1
megahertz
@megahertz
full stack разработчик
CController::forward + правила маршрутизации
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
d4rkr00t
@d4rkr00t
Можно попробовать это сделать правилами роутинга, без одного общего контроллера. А контроллеры, можно вызвать так:

list($controller) = Yii::app()->createController('site');
echo $controller->actionIndex();
Ответ написан
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Довольно тривиальная задача. Решается своим URL менеджером. Просто вам придется где-то хранить список всех урлов и соответствующий раут и параметры. Был такой экстеншен, помниться. Где-то с год назад его использовал. Но при необходимости такой пишется за час.
Ответ написан
@tnz
Так тоже не получится.
в forward() вызывается CWebApplication::runController($route) без обработки. А при изначальном вызове парсится урл из запроса, параметры заносятся в _REQUEST и все такое:
$route=$this->getUrlManager()->parseUrl($this->getRequest());
$this->runController($route);

Так что надо сделать примерно вот так:
$request = Yii:app()->getRequest();
$request->pathInfo = $this->createUrl('/page/test', array('id'=>12));
$route=$this->getUrlManager()->parseUrl($request);
$this->runController($route);

Но я совсем не уверен, что вам удастся таким образом установить pathInfo в реквесте, так что еще проще
вручную записывать параметры в $_REQUEST[«id»]=$_GET["$id"]=12;

Но выглядит это все добро совсем не кошерно. Мне кажется удобней будет переписать UrlManager на свой лад. Просто если у вас запросы все обрабатываются в одном контроллере, который неведомым образом знает куда какой форвардить, то лучше это добро переписать внутрь UrlManager-a. Да и через него урлы формируются для новых страниц (вы же их не жестко прописываете?). Однажды там описать правила или хранить их в базе или где там надо и все.

Из описания проблемы не очень понятно… Если у вас есть несколько контроллеров Page, Product,… и есть урлы вида page1.html, product-cool.html соответственно, то и проблемы-то нет. Просто надо переписать правила роутинга для этих контроллеров. Вот для Page, например
'page<id:\d+>'=>'page/index', //$id перейдет в indexAction($id)

Для Product тож придумать можно
'product-<name:\w+>'=>'product/index', //$name перейдет в indexAction($name)
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы