Yii2自己的过滤器“处理另一个错误时出错”

时间:2018-06-12 08:21:23

标签: php yii2 yii2-basic-app

下午好。

我在Yii2基础项目中创建了自己的过滤器:

class LanguageFilter extends Behavior
{
    /**
     * @var string
     */
    public $shortLanguage;

    /**
     * Declares event handlers for the [[owner]]'s events.
     * @return array events (array keys) and the corresponding event handler methods (array values).
     */
    public function events()
    {
        return [Controller::EVENT_BEFORE_ACTION => 'beforeAction'];
    }

    /**
     * @param ActionEvent $event
     * @return bool
     * @throws BadRequestHttpException
     */
    public function beforeAction($event)
    {
        if (null === $this->shortLanguage){
            throw new BadRequestHttpException('Parameter "shortLanguage" is not defined.');
        }

        $langModel = Language::find()->where([
            'shortName' => $this->shortLanguage
        ])->one();

        if (null === $langModel){
            throw new BadRequestHttpException('There are not any data for language: '.$this->shortLanguage);
        }

        Yii::$app->language = $langModel->locale;

        return true;
    }
}

并在控制器中使用它:

class BaseController extends Controller
{
    /**
     * @var string
     */
    protected $shortLanguage;

    /**
     * Initialize.
     */
    public function init()
    {
        $this->defaultAction = 'index';

        $this->layout = '@app/views/layouts/base';

        $this->shortLanguage = Yii::$app->request->get('shortLanguage');

        $this->view->params['shortLanguage'] = $this->shortLanguage;

        $this->view->params['pages'] = Page::getMenu();

        parent::init();
    }

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            'language' => [
                'class' => LanguageFilter::class,
                'shortLanguage' => $this->shortLanguage
            ],
            'access' => [
                'class' => AccessControl::class,
                'rules' => [
                    [
                        'allow'   => true,
                        'actions' => ['reg', 'login'],
                        'roles'   => ['?'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['logout'],
                        'roles' => ['@'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['index', 'about', 'contact'],
                        'roles' => ['?', '@'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['error'],
                        'roles' => ['?', '@'],
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::class,
                'actions' => [
                    'index' => ['get'],
                    'logout' => ['post', 'get'],
                ],
            ],
        ];
    }

    /**
     * @inheritdoc
     */
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
        ];
    }
}

在Web配置文件错误处理程序中:

'components' => [
    ...
    ...
    'errorHandler' => [
        'errorAction' => 'base/error',
    ],
    ...
    ...
]

但是当过滤器抛出异常时,错误处理程序会显示错误消息WITHOUT TEMPLATE !!!而另一个错误。

An Error occurred while handling another error:
yii\web\BadRequestHttpException: There are not any data for language: fr in C:\xampp\htdocs\pack-develop\filters\LanguageFilter.php:44
Stack trace:
#0 [internal function]: app\filters\LanguageFilter->beforeAction(Object(yii\base\ActionEvent))
#1 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Component.php(627): call_user_func(Array, Object(yii\base\ActionEvent))
#2 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Controller.php(274): yii\base\Component->trigger('beforeAction', Object(yii\base\ActionEvent))
#3 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\web\Controller.php(164): yii\base\Controller->beforeAction(Object(yii\web\ErrorAction))
#4 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Controller.php(155): yii\web\Controller->beforeAction(Object(yii\web\ErrorAction))
#5 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Module.php(528): yii\base\Controller->runAction('error', Array)
#6 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\web\ErrorHandler.php(108): yii\base\Module->runAction('base/error')
#7 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\ErrorHandler.php(111): yii\web\ErrorHandler->renderException(Object(yii\web\BadRequestHttpException))
#8 [internal function]: yii\base\ErrorHandler->handleException(Object(yii\web\BadRequestHttpException))
#9 {main}
Previous exception:
yii\web\BadRequestHttpException: There are not any data for language: fr in C:\xampp\htdocs\pack-develop\filters\LanguageFilter.php:44
Stack trace:
#0 [internal function]: app\filters\LanguageFilter->beforeAction(Object(yii\base\ActionEvent))
#1 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Component.php(627): call_user_func(Array, Object(yii\base\ActionEvent))
#2 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Controller.php(274): yii\base\Component->trigger('beforeAction', Object(yii\base\ActionEvent))
#3 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\web\Controller.php(164): yii\base\Controller->beforeAction(Object(yii\base\InlineAction))
#4 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Controller.php(155): yii\web\Controller->beforeAction(Object(yii\base\InlineAction))
#5 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Module.php(528): yii\base\Controller->runAction('index', Array)
#6 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\web\Application.php(103): yii\base\Module->runAction('home/index', Array)
#7 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request))
#8 C:\xampp\htdocs\pack-develop\web\index.php(33): yii\base\Application->run()
#9 {main}

奇怪的是,当其他过滤器(AccessControl,VerbFilter)发出异常时,错误处理程序会通过视图模板正常显示错误消息。

请帮助我理解它的原因!

1 个答案:

答案 0 :(得分:0)

这是一个过滤器而不是行为,我修改过你的过滤器。

use Yii;
use yii\web\Controller;
use yii\base\ActionFilter;
use yii\web\BadRequestHttpException;

class LanguageFilter extends ActionFilter
{
    /**
     * @var string
     */
    public $shortLanguage;

    /**
     * @param ActionEvent $action
     * @return bool
     * @throws BadRequestHttpException
     */
    public function beforeAction($action)
    {
        if ($this->shortLanguage === null && !$action instanceof yii\web\ErrorAction)) {
            throw new BadRequestHttpException('Parameter "shortLanguage" is not defined.');
        }

        $langModel = Language::find()->where([
            'shortName' => $this->shortLanguage,
        ])->one();

        if ($langModel === null && !$action instanceof yii\web\ErrorAction) {
            throw new BadRequestHttpException('There are not any data for language: ' . $this->shortLanguage);
        }

        Yii::$app->language = $langModel->locale;

        return true; //return parent::beforeAction($action);
    }
}