dryk50495 2018-06-12 08:21
浏览 62

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

Good afternoon.

I have created my own filter in Yii2 basic project:

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

And use it in controller:

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',
            ],
        ];
    }
}

In web configuration file error handler:

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

But when the filter throws an exception, the error handler displays an error message WITHOUT TEMPLATE !!! And with another mistake.

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}

The strange thing is that when other filters (AccessControl, VerbFilter) issue exceptions, the error handler displays an error message through the view template normally.

Please help me to understand the reason of it!

</div>
  • 写回答

1条回答 默认 最新

  • dth96108 2018-06-12 11:36
    关注

    It's a filter not behavior, I have modified your filter that works.

    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);
        }
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用
  • ¥15 Web.config连不上数据库
  • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。
  • ¥15 怎么配置广告联盟瀑布流
  • ¥15 Rstudio 保存代码闪退
  • ¥20 win系统的PYQT程序生成的数据如何放入云服务器阿里云window版?
  • ¥50 invest生境质量模块