Yii:自定义错误处理转发

时间:2014-04-22 20:02:47

标签: php yii error-handling

我正在寻找一种在我的Yii 1.1.14应用程序中转发错误处理的方法。方案如下:

假设我有两个模块:ClientModule在/ client /,AdminModule在/ admin /。如果一个url被解析为属于该模块中的任何控制器,则加载控制器,并将errorHandler重新分配给模块级错误处理程序,如下所示:

public function beforeControllerAction($controller, $action)
{
    Yii::app()->errorHandler->errorAction='admin/error';
    return parent::beforeControllerAction($controller, $action);
}

通过这种方式,'admin / admin / error'中存在一个操作(反过来手动指定解析为'admin / error'),它将使用类似的样板处理错误:

public function actionError() {
    if($error=Yii::app()->errorHandler->error)
    {
        if(Yii::app()->request->isAjaxRequest)
            echo $error['message'];
        else
            $this->render('application.views.error.index', $error);
    }
}

同时,另一个模块中存在类似的代码(对于这两个函数)(还有一个ClientModule和一个带有actionError的ClientController自动映射到'client / client / error',重新映射到'client / error')。 / p>

我对这些代码块完全没有问题。 我的问题现在开始

如果我输入了一个无法解析的网址,即使前缀是模块前缀(例如'client / invalid / url'或'client / client / invalid'),也不会创建控制器(因为它确实如此)不存在 - 或者,如在第二个示例中,控制器存在但不存在操作),因此不会调用beforeController,因此自定义错误处理程序(在此示例中:对应于设置$的ClientModule)不会分配aClientController-> actionError)。结果:处理未解析的URL错误的默认ErrorController。

所以,问题

  1. 有什么方法可以将未解析的url(404)错误映射到某个模块,具体取决于前缀? (在我的情况下,假设前缀是安全的,因为我没有将任何模块设置为默认值。)

  2. 或者:有没有办法,在ErrorController-> actionIndex()中,将错误处理转发给其中一个控制器(即转移到admin / admin / error和client / client / error while保持Yii::app()->errorHandler->error状态?

  3. 编辑 - 脚注:如果错误处理代码相同,为什么还要使用其他控制器?因为我在布局中使用了那些控制器提供的附加数据(例如菜单,头菜单)。

1 个答案:

答案 0 :(得分:0)

再次找到答案(我的小辈没有限制 - ,我需要的方法名称具有确切名称:forward !! )。

使用CController->forward('module/controller/action')方法中的ErrorController->actionError我可以在任何地方发送。我还改变了另一个业务逻辑条件,并且不再在模块构造函数中分配自定义错误处理程序,但我仍然使用这些控制器作为' error / index'的前向目标。取决于记录的用户类型(即发生错误,用户是客户端=>转发到客户端/客户端/错误,管理员导致admin / admin /错误,并且没有记录用户执行错误处理错误/ index像往常一样)。

public function actionIndex() {
    if (Yii::app()->user->getState('client'))
    {
        $this->forward('client/client/error');
    }
    if (Yii::app()->user->getState('staff'))
    {
        $this->forward('admin/admin/error');
    }

    //usual boilerplate here
    if($error=Yii::app()->errorHandler->error)
    {
        if(Yii::app()->request->isAjaxRequest)
            echo $error['message'];
        else
            $this->render('index', $error);
    }
}