草庐IT

php - 在 Yii2 中运行行为代码之前获取 Controller 操作

coder 2024-01-03 原文

我正在尝试在 Yii2 Controller 中执行一些代码,因为我需要模型中的一些代码可以在 behaviors 部分中访问,这样我就可以传递模型作为参数并避免运行重复查询;然而,我还需要能够找出正在调用的 action,但我运气不佳。

我已经尝试使用 beforeAction 但它似乎在 AFTER behaviours 代码运行后运行,所以这对我没有帮助。

然后我尝试使用 init,但似乎 action 无法通过 $this->action->id 使用点。

一些示例代码:

class MyController extends Controller { 

    public $defaultAction = 'view';

    public function init() {

        // $this->action not available in here

    }

    public function beforeAction() {

        // This is of no use as this runs *after* the 'behaviors' method

    }

    public function behaviors() {
        return [
            'access' => [
                'class' => NewAccessControl::className(),
                'only' => ['view','example1','example2'],
                'rules' => [
                    [
                        'allow' => false,
                        'authManager' => [
                            'model' => $this->model,
                            'other_param' => $foo,
                            'other_param' => $bar,
                        ],
                        'actions' => ['view'],
                    ],
                    // everything else is denied
                ],
            ],
        ];
    }

    public function viewAction() {

        // This is how it is currently instantiated, but we want to instantiate *before* the behavior code is run so we don't need to instantiate it twice
        // but to be able to do that we need to know the action so we can pass in the correct scenario

        $model = new exampleModel(['scenario' => 'view']);

    }

}

authManager 只是对 AccessRule 类扩展中的成员变量 的引用。

无论如何我可以做到这一点吗?

最佳答案

好吧,如果我没猜错,你正在寻找这样的东西:

public function behaviors()
{
    $model = MyModel::find()->someQuery();
    $action = Yii::$app->controller->action->id;
    return [
         'someBehavior' => [
             'class' => 'behavior/namespace/class',
             'callback' => function() use ($model, $action) {
                 //some logic here
             }
         ]
    ];
}

因为 behaviors() 只是一个方法,您可以声明任何变量并在其中添加您想要的任何逻辑,您必须遵循的唯一约定 - 返回类型必须是数组

如果您使用自定义行为,则可以使用 events() 方法,您可以将行为的方法绑定(bind)到特定事件。例如

class MyBehavior extends Behavior
{
    public function events()
    {
        return [
            \yii\web\User::EVENT_AFTER_LOGIN => 'myAfterLoginEvent',
        ];
    }

    public function myAfterLoginEvent($event)
    {
        //dealing with event
    }
}

在此示例中,myAfterLoginEvent 将在用户成功登录应用程序后执行。 $event 变量将由框架传递,并且根据事件类型,它将包含不同的数据。阅读about event object

更新:

正如我现在所见,我的回答对事件和行为更为笼统。现在,当您添加代码时,我可以建议您使用以下代码覆盖行为 beforeAction($action) 方法:

public function beforeAction($action)
{
    $actionID = $action->id;
    /* @var $rule AccessRule */
    foreach ($this->rules as &$rule) {
        $model = &$rule->authManager['model'];
        //now set model scenario maybe like this
        $model->scenario = $actionID;
    }
    //now call parent implementation 
    parent::beforeAction($action);
}

另请查看AccessControl implementation of beforeAction方法,它会为每个规则调用 allows 方法,并将当前操作作为参数传递给它。因此,如果您有扩展AccessRule 的类,您可以覆盖allows($action, $user, $request) 方法或matchCustom($action) 方法来设置适当的模型场景。希望这会有所帮助。

另一种选择:

覆盖 Controller 的 runAction($id, $params = []) 方法。这里 $id 是 actionID - 正是您需要的。检查 id,设置合适的模型场景并调用 parent::runAction($id, $params);

关于php - 在 Yii2 中运行行为代码之前获取 Controller 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31143273/

有关php - 在 Yii2 中运行行为代码之前获取 Controller 操作的更多相关文章

  1. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  2. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  3. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  4. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  5. ruby-on-rails - rails : How to make a form post to another controller action - 2

    我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak

  6. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  7. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  8. ruby-on-rails - 浏览 Ruby 源代码 - 2

    我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru

  9. ruby-on-rails - 如何在 Rails Controller Action 上触发 Facebook 像素 - 2

    我有一个ruby​​onrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素

  10. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

随机推荐