【问题标题】:Should I use Laravel Middleware?我应该使用 Laravel 中间件吗?
【发布时间】:2016-05-04 17:46:10
【问题描述】:

我有一个 Laravel 应用程序,它需要获取一些我的大多数控制器都需要使用的配置变量。 因此,这似乎是使用中间件的最佳时机。 这是对中间件的正确使用吗?如果是这样,一旦中间件获得配置变量,最好将它们添加到请求对象中,以便我的控制器可以访问它们? 感谢任何响应者。 J

【问题讨论】:

  • 配置变量是静态的还是动态的。
  • 一旦在中间件中定义,它们就是静态的。
  • 您能否添加更多信息,例如您使用变量的目的、它们将持续多长时间等。
  • 可以使用中间件设置配置变量。它不必用于限制访问。它可用于对多个路由进行分组并向它们公开某些值,同时将这些配置值限制为其他路由。您可以随意设置这些变量。以你想要的方式使用它并没有错。
  • 谢谢 N.B.为您的回应。我想我真的想弄清楚何时使用哪种方法。即最佳实践是使用中间件、基本控制器还是 felipsmartins 建议的服务提供商。 (我真的很纠结何时使用服务提供商!)

标签: php laravel laravel-5 middleware


【解决方案1】:

不,绝对!

实际上(根据您所写的),最好的方法是创建一个应用程序服务并将该服务注册到服务容器 - App\Providers\AppServiceProvider(在 app/Providers/AppServiceProvider.php 中)。

类似这样的:

<?php
# The Config Service:

namespace App\Services;

/**
 * Config Manager
 */
class Config
{
    /** @var SomeDependency */
    protected $dependency;

    public function __construct(SomeDependency $dependency)
    {
        $this->dependency = $dependency;
    }

    public function getVar($var)
    {
        // ...
    }
}

在您的服务提供商中:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    //...

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {

        $this->registerConfigManager();

    }

    public function registerConfigManager()
    {
        $this->app->singleton('config_service', function ($app) {
            return new \App\Services\Config(new \SomeNamespace\SomeDependency);
        });
    }

    //...
}

现在您可以通过app() 访问服务容器,如下所示:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class MyController extends Controller
{
    public function index(Request $request)
    {
        app('config_service')->getVar('key');
        //...
    }
}

【讨论】:

  • 谢谢 felipsmartins,其他人是否同意这是使用服务提供商的好时机?
  • @jon 其实不需要创建服务提供者,只需要创建一个类,然后在容器中注册为应用服务即可。这既简单又不错。
  • 谢谢两位,这就是我真正感到困惑的地方,这是使用中间件、服务提供者或简单地将逻辑添加到控制器的最佳实践。实际上,服务提供者是一种使服务全球可访问的方式?.. 还是我遗漏了什么?
  • 是的,使用此解决方案,提供程序将可以在应用程序上下文中访问。由您决定哪种解决方案更适合您:在应用程序上下文或控制器上下文中访问
  • @jon 想想中间件,比如用于持续请求的 HTTP 过滤器。服务只是通过应用程序上下文在多个地方重用的简单类/对象(即:邮件服务)。关于控制器逻辑,请注意在这种情况下您不会重用另一个控制器内部的逻辑或过程。
【解决方案2】:

IMO,中间件用于预处理请求、限制用户访问和其他安全相关。

我只需在主控制器类中加载配置并在扩展控制器中使用它。

例如:

基础控制器

namespace App\Http\Controllers;

uses goes here ...;

class Controller extends BaseController
{
    protected $configs = [];

    public function __construct() {
        $this->loadConfigs();
    }

    protected function loadConfigs()
    {
        //read configuration files or tables in database 
        //and put the values into '$this->configs';
    }

}

用户控制器

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;

class User extends Controller
{
    public function index()
    {
        echo $this->configs['toolbar.color']; //just an example
    }
}

【讨论】:

  • 存在中间件以在让请求到达您的控制器之前检查条件。它们用于预处理后处理。它与安全无关,它与条件相关(一个条件可以是“用户必须经过身份验证)。它可用于设置变量和请求到达控制器之前所需的一切。此评论是为了突出您关于正在使用的中间件的声明安全是不正确的。
  • 非常感谢 Carlos,这是有道理的,所以基本上只需使用中间件进行过滤,并将我的大多数控制器可能需要的逻辑放在基本控制器中。这在我的脑海中很好:)
  • 虽然我看到 N.B 不同意。所以NB你会把我的要求添加为中间件吗?
  • 恕我直言,这应该是你的路要走。如果你必须处理某些东西,中间件就是你要走的路。但是,在这种情况下,您似乎不需要这样做。
猜你喜欢
  • 2011-05-19
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2014-03-15
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多