当找不到控制器时通过默认控制器路由 zend 请求

发布于 2024-08-30 01:05:44 字数 897 浏览 4 评论 0原文

下面是我的 Bootstrap 类中定义的函数。我肯定错过了 Zend 路由和调度方式中的一些基本内容。我想要完成的事情很简单:对于任何因任何原因而无法调度的请求 /foo/bar/* ,请尝试 /index/foo/bar/。我遇到的问题是,当 FooController 存在时,我得到 Action“foo”不存在。基本上,isDispatchable 始终为 false。

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();
    }

Below is a function defined in my Bootstrap class. I must be missing something fundamental in the way Zend does routing and dispatching. What I am trying to accomplish is simple: For any request /foo/bar/* that is not dispatchable for any reason try /index/foo/bar/. The problem I'm having is when the FooController exists I get Action "foo" does not exist. Basically, the isDispatchable is always false.

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();
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

带上头具痛哭 2024-09-06 01:05:44

所以这似乎可行,但不是最好的答案,因为它只是删除所有参数。我可能会尝试在插件中转发到 /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');
    }
  }
}

So this seems to work, but is not the best answer as it simply drops all the params. I might try shortly doing a forward to /index/[original uri] within the plugin:

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');
    }
  }
}
夏末的微笑 2024-09-06 01:05:44

如果我理解你的想法正确的话
你会尝试使用 __call 魔术方法吗?
然后使用 $this->_redirect(); 到您的默认操作,例如

更多信息在这里 http://php.net/manual/en/language.oop5.overloading.php

更新

如果您打开 Zend/Controller/Action。 php on line 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 将运行
这个想法只是关于不存在的行动
如果控制器不存在,它将无法工作

if i understand your idea right
would you try to use __call magic method ??
then use $this->_redirect(); to your default action for example

more info are here http://php.net/manual/en/language.oop5.overloading.php

UPDATE

if you opened Zend/Controller/Action.php on line 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);
    }

what i meant to do is to extend this class and override __call function exactly to be

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 
        }
}

and make sure your controller extend your newly created class

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

so if some how you called inexistent action __call will run
this idea was about inexistent action only
it won't work if the controller doesn't exist

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文