如何在 Laravel 中跨控制器重用代码

How to Reuse Code Across Controllers in Laravel

我是 Laravel 的新手(总体上对 MVC 概念来说相对较新)并且已经看了几个小时的教程并阅读了许多其他教程,但是我没有完成一个简单的常见任务:什么是跨控制器重用系统(例如 CMS)中相同基本元素的最佳方式?

场景:

我有一个内容管理系统,想为每种类型的功能使用不同的控制器:例如用于操作帖子的帖子控制器、用于管理用户的用户控制器、用于菜单项的菜单控制器等。大多数教程推荐这种类型的工作流程。

然而,在实际的 CMS 前端中,我有许多动态的公共元素(来自数据库)但仍需要在所有控制器中显示。例如,菜单(来自数据库),当前用户的详细信息(用户名和根据权限的相关按钮)等。使用 Blade 向用户(前端)显示它很容易,但我不能不知道在后端执行此操作的最佳方法。

例如,如果每个控制器分别从数据库中获取菜单,那将是(缺乏)代码重用的噩梦。另一方面,似乎没有一个中心位置可以插入此代码并将其传递到所有控制器的视图上。我相信 Laravel 开发人员已经想到了这种极其常见的场景。实施它的最佳方法是什么?

您可以 View::share 扩展其他控制器的基本控制器中的变量,如下所示:

基地控制器

protected $variable;

public function __construct() 
{
    $this->variable= Model::all();
    View::share('variable', $this->variable);
}

然后只需在扩展基本控制器的其他控制器中使用 $this->variable 即可获取您的变量。

您可以尝试的另一件事是注册一个单例并改用这种方法

在某些文件中它是自动加载的或者它的命名空间是自动加载的

   App::before(function($request) 
       {
        App::singleton('variable', function(){
            $variable= Model::all();
            return $variable;
        });

然后在您的控制器中使用 $variable= app('variable');

这正是 View Composers 的用途!

View Composer 允许您注册在呈现特定视图之前执行的回调。通常你在 Service Provider 中注册它们。您可以使用现有的 AppServiceProvider 或为此创建一个新的 ComposerServiceProvider

对于名称为 menu

的视图,这将是一个非常基本的示例
public function boot(){
    View::composer('menu', function($view){
        $menu = DB::table('menu')->get();
        $view->with('menu', $menu);
    });
}

您还可以指定包含作曲家逻辑的 class。 Read more about that in the docs