在任何控制器的任何操作之前执行我的代码

Posted

技术标签:

【中文标题】在任何控制器的任何操作之前执行我的代码【英文标题】:Execute my code before any action of any controller 【发布时间】:2015-01-26 14:31:49 【问题描述】:

我想检查我的用户是否在他的个人资料中填写了某些字段,然后他才能访问任何控制器的任何操作。 例如

if(empty(field1) && empty(field2))

   header("Location:/site/error")

在 yii1 中,我可以在 init() 函数中的 protected\components\Controller.php 中执行此操作 但是在 yii2 中,我不确定将代码放在哪里。我无法修改核心文件,但不确定如何在我的高级应用程序的后端进行操作。

我知道我可以使用 beforeAction(),但我有太多控制器无法做到这一点并跟踪每个控制器

【问题讨论】:

【参考方案1】:

如果您需要在每个控制器和操作之前执行代码,您可以执行以下操作:

1 - 将组件添加到您的组件目录中,例如(MyGlobalClass):

namespace app\components;
class MyGlobalClass extends \yii\base\Component
    public function init() 
        echo "Hi";
        parent::init();
    

2 - 将MyGlobalClass 组件添加到配置文件中的组件数组中:

'components' => [
    'MyGlobalClass'=>[
        'class'=>'app\components\MyGlobalClass'
     ],
     //other components

3 - 将MyGlobalClass 添加到配置文件中的bootstarp 数组中:

'bootstrap' => ['log','MyGlobalClass'],

现在,您可以在每次操作之前看到Hi

请注意,如果您不需要使用EventsBehaviors,您可以使用\yii\base\Object 代替\yii\base\Component

【讨论】:

@MiskoMali 你使用模块吗? 另外,需要和表单交互吗?或者您需要在每个控制器的操作之前执行一些代码?如果是表格,如果你使用模型,你可以使用beforeValidate() @MiskoMali 好吧,如果你使用模块,你可以在init() 方法中编写代码,该方法将在该模块的每个控制器之前执行 我只需要在每个动作之前执行一些代码,与任何表单或数据库无关。我在供应商文件夹中使用模块,而不是在后端文件夹中。在后端文件夹中,我只使用 Controller 和 Models @MihaiP。不,亲爱的,这只是一个将在应用程序引导中启动的类(组件、对象、事件或行为)。一旦应用程序运行,这个类的init() 方法就会被调用。【参考方案2】:

创建一个新的控制器

namespace backend\components;
class Controller extends \yii\web\Controller 
    public function beforeAction($event)
    
        ..............
        return parent::beforeAction($event);
    

你所有的控制器现在应该扩展 backend\components\Controller 而不是 \yii\web\Controller。有了这个,你应该修改每个控制器。我会选择这个解决方案。

我相信您也可以用另一个类替换 1 个类(因此无需更改任何控制器),例如

\Yii::$classMap = array_merge(\Yii::$classMap,[
                '\yii\web\Controller'=>'backend\components\Controller',
            ]);

在此处查看更多详细信息:http://www.yiiframework.com/doc-2.0/guide-tutorial-yii-integration.html 我从此处获取代码:https://github.com/mithun12000/adminUI/blob/master/src/AdminUiBootstrap.php

你可以把它放在你的 index.php 文件中。但是,请确保您很好地记录此更改,因为有人会来尝试调试您的代码,这会完全混淆。

【讨论】:

【参考方案3】:

或者,https://github.com/yiisoft/yii2/blob/master/docs/guide/security-authorization.md 使用 RBAC,根据规则限制对控制器操作的访问。为什么要根据用户字段限制对控制器操作的访问超出了我的范围。如果您在此处设置限制,您将无法访问任何内容(包括登录表单)。

【讨论】:

【参考方案4】:

只需将配置文件添加到 $config 数组中:

    'on beforeAction' => function ($event) 
           echo "Hello";
    ,

【讨论】:

这个最适合处理“全局” beforeAction 事件。 是的,它非常好,我认为这将是最好的答案!【参考方案5】:

只是我认为配置文件中的这段代码可以帮助你:

'on beforeAction' => function ($event) 
      // To log all request information
,
'components' => [
    'response' => [
        'on beforeSend' => function($event) 
            // To log all response information
        ,
    ],
];

【讨论】:

以上是关于在任何控制器的任何操作之前执行我的代码的主要内容,如果未能解决你的问题,请参考以下文章

如何通过任何代码、脚本执行以下操作

确定我的代码在 MFC 中执行所用的时间

Groovy:在调用任何方法之前和之后透明地执行代码

如何使用 CAShapeLayer 使我的 UIBezierPath 动画?

Spyder IDE 中的 iPython 控制台挂起任何代码执行

在此上下文中启动了第二个操作