2010-04-27 1 views
0

Ниже приведена функция, определенная в моем классе Bootstrap. Я должен упустить что-то фундаментальное в том, как Zend выполняет маршрутизацию и диспетчеризацию. То, что я пытаюсь сделать, прост: для любого запроса /foo/bar/*, который по какой-либо причине не может быть отправлен, попробуйте /index/foo/bar/. Проблема, с которой я столкнулась, - это когда существует FooController, я получаю Action "foo" does not exist. В принципе, значение isDispatchable всегда неверно.Маршрутизация запроса zend через контроллер по умолчанию, когда контроллер не найден

public function run() { 
     $front = Zend_Controller_Front::getInstance(); 
     $request = $front->getRequest(); 
     $dispatcher = $front->getDispatcher(); 
     //$controller = $dispatcher->getControllerClass($request); 
     if (!$dispatcher->isDispatchable($request)) { 
      $route = new Zend_Controller_Router_Route(
       ':action/*', 
       array('controller' => 'index') 
      ); 
      $router = $front->getRouter(); 
      $router->addRoute('FallBack', $route); 
     } 
     $front->dispatch(); 
    } 

ответ

0

если я понимаю вашу идею прямо бы вы пытаетесь использовать __call магический метод ?? затем использовать $this->_redirect(); для вашего действия по умолчанию, например

Более подробную информацию здесь http://php.net/manual/en/language.oop5.overloading.php

UPDATE

если вы открыли Zend/Controller/action.php на линии 480

public function __call($methodName, $args) 
    { 
     require_once 'Zend/Controller/Action/Exception.php'; 
     if ('Action' == substr($methodName, -6)) { 
      $action = substr($methodName, 0, strlen($methodName) - 6); 
      throw new Zend_Controller_Action_Exception(sprintf('Action "%s" does not exist and was not trapped in __call()', $action), 404); 
     } 

     throw new Zend_Controller_Action_Exception(sprintf('Method "%s" does not exist and was not trapped in __call()', $methodName), 500); 
    } 

что я хотел сделать, это расширить этот класс и переопределить функцию __call точно так, чтобы она была

classs My_Controller_Action extends Zend_Controller_Action{ 
    public function __call($methodName, $args) 
     { 
      ///// do your magic here ......redirection or logging the request or what ever 
     } 
} 

и убедитесь, что ваш контроллер расширить вновь созданный класс

class FooController extends My_Controller_Action 
{ 
    public function indexAction() 
    { 
     // action body 
    } 
} 

так что если какой-то, как вы назвали несуществующее действие __call будут работать эта идея о несуществующем действии только он не будет работать, если контроллер не существует

+0

Я не уверен, '__call' метод вы имеете в виду? Какой класс? Более конкретно, класс контроллера в этом случае не существует. Причина, по которой я хочу ввести новый маршрут, заключается в том, что я могу запустить цикл и правильно убрать маршрутизатор всего, что следует за:: action /. Однако я понимаю, что это невозможно сделать в бутстрапе, поскольку маршрутизатор и диспетчер еще не готовы. Думаю, мне, возможно, придется создать плагин или что-то еще. –

+0

@brett Я обновил свой ответ, надеюсь, мой ответ поможет вам – tawfekov

0

Это похоже на работу, но это не лучший ответ, поскольку он просто отбрасывает все параметры. Я мог бы попробовать в ближайшее время делать вперед к /index/[original uri] внутри плагина:

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { 
    protected function _initRoute() { 
    $front = Zend_Controller_Front::getInstance(); 
    $routes = array(
     'FallBack' => new Zend_Controller_Router_Route(
     ':controller/:action/*', 
     array('controller' => 'index', 'action' => 'index') 
    ) 
    ); 
    $router = $front->getRouter(); 
    $router->removeDefaultRoutes(); 
    $router->addRoutes($routes); 
    $front->setRouter($router); 
    return $router; 
    } 

    protected function _initPlugin() { 
    $front = Zend_Controller_Front::getInstance(); 
    $front->registerPlugin(new My_Controller_Plugin_FallBack()); 
    } 
    } 

class My_Controller_Plugin_FallBack extends Zend_Controller_Plugin_Abstract { 
    public function preDispatch(Zend_Controller_Request_Abstract $request) { 
    $front = Zend_Controller_Front::getInstance(); 
    $dispatcher = $front->getDispatcher(); 
    $router = $front->getRouter(); 
    if (($router->getCurrentRouteName() == 'FallBack') && 
     !$dispatcher->isDispatchable($request)) { 
     $request->setActionName($request->getControllerName()); 
     $request->setControllerName('index'); 
    } 
    } 
} 
Смежные вопросы