Yii2:将行为附加到每个控制器

Yii2:将行为附加到每个控制器,yii2,Yii2,如何将行为附加到应用程序中的所有web控制器 我理解依赖注入在理论上是可能的,所以我假设类似的东西会起作用: Yii::$container->set('Yii\web\Controller'[ “作为我的行为”=>[ 'class'=>'app\behaviors\MyBehavior', ], ]); 但是,DI需要精确的类匹配(附加到父类将不起作用)。无法提前知道所有控制器名称,尤其是当大多数控制器名称来自第三方模块时 有没有其他方法可以做到这一点 编辑:其目的是动态添加控制器过滤器(这

如何将行为附加到应用程序中的所有web控制器

我理解依赖注入在理论上是可能的,所以我假设类似的东西会起作用:

Yii::$container->set('Yii\web\Controller'[
“作为我的行为”=>[
'class'=>'app\behaviors\MyBehavior',
],
]);
但是,DI需要精确的类匹配(附加到父类将不起作用)。无法提前知道所有控制器名称,尤其是当大多数控制器名称来自第三方模块时

有没有其他方法可以做到这一点


编辑:其目的是动态添加控制器过滤器(这只是一种特殊类型的行为)。因此,在事件期间附加该行为是不够的,因为它是在请求筛选之后很长时间触发的。

我必须说,这是一个有趣的问题。我找不到解决这个问题的简单方法,但我有这个想法。您可以利用Yii autoloader加载您的
Yii\web\Controller
版本,而不是原始版本

为此:

  • 从供应商处复制原始文件并将其放置在应用程序中

  • 不要更改原始名称空间和名称

  • 在其中添加您的行为配置(或只是行为的代码,等等)

  • 将这一行添加到下面每次应用程序运行时都会调用的位置(如入口点文件或引导文件,它必须在
    vendor/yiisoft/yii2/Yii.php
    文件是
    必需的
    之后调用):

  • 现在,每次autoloader尝试加载
    yii\web\Controller
    时,它都会加载您的版本,所以它应该可以像您希望的那样工作

    明显的缺点是,在升级Yii以使其最新时,您必须手动检查原始文件是否未更新。

    在控制器版本的事件之前触发模块(和应用程序的)
    。您可以利用它将行为附加到当前控制器

    例如,在web.php配置中:

    返回[
    'on beforeAction'=>函数(){
    Yii::$app->controller->attachBehavior(
    “我的行为”,
    \app\behaviors\MyBehavior::class
    );
    },
    //…其他配置
    ];
    
    当然,缺点是行为从一开始就没有附加


    注意:如果您的目标是为每个控制器附加一个过滤器,您只需将其附加到应用程序本身,而不是控制器。

    哇,您是对的。简单地将过滤器附加到应用程序是可能的!它甚至在文档()中这样说。供将来参考:“除了控制器,您还可以在模块或应用程序中声明筛选器。这样做时,筛选器将应用于属于该模块或应用程序的所有控制器操作”
    Yii::$classMap['yii\web\Controller'] = ''; // replace '' with the path to your version
                                               // of yii\web\Controller