Laravel - 需要从模型中访问 BaseController 中设置的全局变量
Posted
技术标签:
【中文标题】Laravel - 需要从模型中访问 BaseController 中设置的全局变量【英文标题】:Laravel - Need to access a global variable set in BaseController from within a model 【发布时间】:2016-04-05 13:15:25 【问题描述】:我正在创建一个更改日志系统,用于复制对表所做的更改。这个函数本质上使用了 beforeUpdate() 钩子,并允许我为该表在 ChangeLog 中制作旧数据的副本。我还想用一些特定的信息来标记它,例如发出请求的 IP 地址和发出请求的用户 ID。
用户 ID 存储在 BaseController 类内部的全局变量中,任何控制器都可以使用 $this->userId 访问该变量,但是,我不希望将用户 ID 显式传递给每个模型调用,所以我希望能够从我的各种模型中访问 $this->userId,但 laravel 模型显然不允许您通过仅引用 $this->userId 来与控制器对话。
谁能告诉我如何解决这个问题?我已经挖掘了几个小时,但找不到任何我需要的东西?
非常感谢, 韦德
【问题讨论】:
我正在使用 Laravel 4 如果您不想传递依赖项,您可以将 ID 存储在会话中并在任何您想要的地方获取它 这看起来是个不错的建议,然后它可以在整个会话中使用,而无需指定特定模型。如果可以的话,我会给这个^,但谢谢! 我已经发布了一个答案,添加了另一种选择 【参考方案1】:基本上如果你不想传递依赖,你有两种方法:
1 - 使用会话:您可以将 ID 存储在会话中并在任何您想要的地方获取它
2 - 创建一个服务提供者或一个类来存储您想要的数据并在以后使用应用注册表检索它:
为此,您可以创建一个类来存储数据,然后将实例绑定到服务容器上:
$service = new ServiceClass( $id ); //this will contain the data you need: i.e the ID
$app->instance('your_key', $service); //store the instante in the IoC Container
现在你可以在任何你想要的地方取回实例:
$service = $app->make('your_key');
你也可以创建一个 Facade 来访问它
最后一点:以这种方式编写的代码闻起来像“糟糕的全局东西”,所以你应该考虑尽可能将依赖传递给你的模型
【讨论】:
在我看来,使用会话是最好的方法,因为这正是它应该用于的用途,并且比使其成为基本控制器的属性更有意义。话虽如此,使用服务容器有一种更简单的方法。可以简单地将值绑定到它,而无需额外的类。App::bind('userid', function() return 'someUserId' );
.
@user3158900 : 你说的是真的,一个类更适合存储更复杂的数据
这是一种极端情况。我通常会通过控制器将我需要的东西传递给模型,但是我正在使用 beforeChange() 钩子长时间进行基于“完整记录”的更改,我想全局获取该用户 ID,而无需将其传入。在这种情况下,会话完美地满足了我的需求,但我真的很喜欢你们发布的其他想法。我也可以尝试应用注册表的想法。我不知道这个功能。我基本上是在原始记录被任何更改覆盖之前创建一个副本,并添加一些信息来识别谁进行了更改。【参考方案2】:
通过创建范围,您可以获得模型中的用户 ID 值。 例如,在文章模型中,如果我想检查文章的作者是否是当前用户,我可以将自己的范围设置为:
public function scopeUserid($query,$id)
$query->where('user_id',$id);
在控制器中,您可以传递用户ID
$allArticlesFromCurrentAuthor = Article::userid($this->userId)->get();
希望对你有帮助。
【讨论】:
您忘记了return
声明。 :) return $query->where('user_id',$id);
感谢您的帮助。这个解决方案很棒,但看起来我需要将 userId 传递给我需要使用它的每个模型,对吗?
感谢Thomas 的更正,但即使没有return 声明它也能正常工作。是的,Wade 我们必须将 userId 作为参数传递给每个模型。以上是关于Laravel - 需要从模型中访问 BaseController 中设置的全局变量的主要内容,如果未能解决你的问题,请参考以下文章