CakePHP 3.5重定向缺少控制器异常

CakePHP 3.5重定向缺少控制器异常,cakephp,cakephp-3.0,Cakephp,Cakephp 3.0,我对CakePHP抛出的丢失的控制器异常感到困惑。 一旦调用未知控制器,它应该在我的登录页面上重定向。 首先,当控制器/操作未知时,我尝试路由到我的standart登录页面 //default routing $routes->connect('/:controller', ['action' => 'index'], ['routeClass' => 'InflectedRoute']); $routes->connect('/:controller/:action/*

我对CakePHP抛出的丢失的控制器异常感到困惑。 一旦调用未知控制器,它应该在我的登录页面上重定向。 首先,当控制器/操作未知时,我尝试路由到我的standart登录页面

//default routing
$routes->connect('/:controller', ['action' => 'index'], ['routeClass' => 'InflectedRoute']);
$routes->connect('/:controller/:action/*', [], ['routeClass' => 'InflectedRoute']);
$routes->connect('/', ['controller' => 'Users', 'action' => 'login']);
//redirect if controller is not known 
$routes->connect('/*', ['controller' => 'Users', 'action' => 'login']);
然而,这根本不起作用,所以我在谷歌上搜索了很多,结果发现你应该抓住一个丢失的控制器,而不是重新路由。我找不到哪里可以发现错误,关于它的文章也很少

有人已经和它有关系了吗?

简短回答 据我所知,捕获
MissinControllerException
只能通过在Cakephp中自定义流来完成

更长的答案 要获得想要的结果,您需要执行以下操作

如果在
应用程序
类中使用
中间件
,则需要通过注释掉以下行来禁用错误处理中间件:

          ->add(ErrorHandlerMiddleware::class)
接下来,您需要用一个自定义的CakePHP错误处理程序覆盖默认的CakePHP错误处理程序。因此,在
src\Error
中创建文件
AppError.php
,其内容如下:

class AppError extends ErrorHandler
{

    public function _displayException($exception)
    {
        if($exception instanceof MissingControllerException){
            $response = new Response();
            $response = $response->withLocation(Router::url(
                ['controller'=>'Users', 'action'=>'login'])
            );
            $emitter = new ResponseEmitter();
            $emitter->emit($response);
        }else{
            parent::_displayException($exception);
        }
    }
}
最后,在
bootstrap.php
文件中,您需要注册新的错误处理程序。根据文档,需要添加以下内容:

$errorHandler = new \App\Error\AppError();
$errorHandler->register();
潜在问题 执行此重定向将隐藏所有丢失的控制器异常。这可能会在URL中出现输入错误的情况下给您带来麻烦,因为您将不再得到明确的错误,而是被重定向到登录页面。
error.log
文件仍应显示原始异常

祝你好运

潜在问题2-CakePHP>=3.6.x
正如ndm在评论中指出的,禁用错误处理中间件并不总是一个好主意,尤其是对于CakePHP3.6。在这种情况下,更好的解决方案是扩展ErrorHandling中间件并注册它。

您可以尝试使用自定义异常呈现程序处理此异常:

在src/Error中创建一个名为eg MyExceptionRenderer.php的新文件,并在其中处理缺少的控制器异常:

namespace App\Error;

use Cake\Error\ExceptionRenderer;

class MyExceptionRenderer extends ExceptionRenderer
{
    public function missingController($error)
    {
        return $this->controller->redirect("/");
    }
}
您还需要在config/app.php中启用此自定义呈现程序:

'Error' => [
    'errorLevel' => E_ALL,
    'exceptionRenderer' => 'App\Error\MyExceptionRenderer',
    'skipLog' => [],
    'log' => true,
    'trace' => true,
],
这样,当出现MissingControllerException时,用户将被重定向到主页面


更多信息可在此处找到:

btw。。我认为您上次的
$routes->connect()
调用不会做任何事情,也不会被删除。事实上,这更简单,但您最终创建了一个新的控制器,以便执行重定向。在ErrorHandler中更早地拦截异常可以更快地发出重定向,而不需要额外的负载:)我认为删除中间件不是一个好主意。全局错误处理程序仅用于正常错误和致命错误,以及在注册错误处理程序中间件之前发生的异常。如果目标是尽早捕获,那么可能最好使用扩展的错误处理中间件,并在重写的
ErrorHandlerMiddleware::handleException()
方法中捕获它,因为这个特定的异常不太可能在更早的时候发生。@ndm,是的,我同意你的看法。我假设看看问题和蛋糕版本,中间件支持不如现在3.6中的好。我将在我的回答中加一条注释。