我在laravel 5.3中有一个系统,它使用40多个控制器,可能有200个视图。
我正在尝试清理代码并使用最佳实践。鉴于某些调用几乎无处不在,将其定义为“半全局”的位置是有意义的。我认为这将在所有控制器扩展的Controller
中。
一个对象为$user
,其中包含子$user->organisations
和$user->organisation->locations
。
以基本控制器(或等效的)方式加载它也会给我带来优势,我可以确保以最佳方式加载子关系,确保任何foreach
样式代码永远不会导致多个小型数据库查找。我想要做的其他一些项目具有类似的数据库优化分支。这些都使用Auth::user()
,它们会影响子对象的权限。
鉴于大约有20个属性/变量用于共享(所有依赖于Auth::user()
),从几乎每种方法中删除这些重复的代码都是一个巨大的改进。
我的目标是能够从任何控制器引用$this->user
,并且已经预先加载了所有子/相关对象。
Laravel 5.3重新组织了加载顺序,因此作为Controller::__construct
的一部分共享登录的用户数据已不再可行。
以下是目前为止尝试的代码:
在Controller::__construct
$this->middleware(function ($request, $next) {
$this->user = Auth::user();
view()->share('user', $this->user);
return $next($request);
});
不出所料,这正确地将$user
变量设置为View级别,而不是Controller级别。虽然我在视图级别使用它,但这没有帮助。
鉴于共有大约20个使用的属性/变量(全部依赖于Auth::user()
),我决定一个Helper至少将其移动到一个集中位置。我将助手实例化为所有控制器的属性:$this->authentication_helper
在示例控制器中:SearchController
:
public function index(Request $request): View
{
$this->authentication_helper->getAuthenticationData($this);
//... logic for the search
}
AuthenticationHelper
做(除其他事项外):
public function getAuthenticationData(Controller $controller) : void
{
$user = Auth::user();
$controller->user = User::with(
organisations.locations', // .. other children .. //
)->find($user->id);
// share to the view
View::share('user', $controller->user);
// ... other $controller property setting
return;
}
我不确定这是否是最佳做法。 编辑 - 之前提出的第二个问题已经解决 - 主要问题仍然存在:
这种方法是否存在问题 - 将这20个左右的变量赋值移动到更高级别的方法是什么。
答案 0 :(得分:0)
您可以使用Laravel DI在控制器中获得授权用户,您的代码应该是这样的
YourControlle extends Controller
{
public function test(Request $request)
$user = $requset->user(); //use auth user
}
答案 1 :(得分:0)
最好的方法是帮助程序(或多个帮助程序,您可以为其创建app\Helpers
命名空间)并在其中包含所有逻辑。
可以使用 Auth Facade从该帮助程序访问Auth::user()
,并在那里使用您的逻辑。
另一种更简单的方法是从您自定义的基本控制器扩展控制器(您将从控制器扩展),并将$user
成员附加到具有受保护可见性的parent::magicMethod()
成员,并将其分享给视图,在构造函数或通过callAction
修改强>
您可以覆盖控制器类
/**
* Execute an action on the controller.
*
* @param string $method
* @param array $parameters
* @return \Symfony\Component\HttpFoundation\Response
*/
public function callAction($method, $parameters)
{
// insert your logic here
return call_user_func_array([$this, $method], $parameters);
}
方法
Event::listen(Authenticated::class, function ($event) {
$this->user = $event->user;
});
您无法通过构造函数访问Auth的原因是因为会话尚未启动。您可以在使用此事件侦听器时捕获它:
spring-tool-suite-3.8.4.RELEASE-e4.6.3-win32.zip
未经过测试
带有闭包的中间件也可以完成工作。让它具有您的逻辑,并在所有控制器中使用它。