Laravel使用Request参数更改绑定

时间:2019-06-14 16:23:53

标签: php laravel laravel-5 dependency-injection service-provider

我正在使用Laravel Framework 5.8.21。我正在尝试将interface绑定到基于Request的{​​{1}}方法中的AppServiceProvider参数的类。

register

,然后将接口注入public function register() { $this->app->bind('App\Contracts\SomeInterface', 'App\Logic\ClassName'); if(Request::has('notification_type') && Request::get('notification_type') == 'email') { $this->app->bind('App\Contracts\SomeInterface', 'App\Logic\SomeotherClassName'); } } 的{​​{1}}方法。

在进行测试时,它始终绑定到Controller。我尝试在__construct()内访问URL,并在运行ClassName时始终返回AppServiceProviderunit tests,方法返回为/,即使从测试中像这样发布到URL。

$this->app->request->getRequestUri();

在使用Postman进行测试时,当我尝试发布GET时,显示为$this->post('/notification', [ 'notification_type' => 'email', ])->assertJson( 'message-push-status' => true, ]);

2 个答案:

答案 0 :(得分:1)

这是可能的。 AppServiceProvider或任何其他服务提供商的注册方法有权访问请求参数

可以如下访问:

public function register()
{
  $this->app->bind('SomeInterface', function($app) {
    return new SomeClass(request()->some_parameter);
  });
}

答案 1 :(得分:0)

您将无法可靠地使用服务提供商内部的当前请求信息。

首先,通常的最佳做法是不直接依赖register()方法中的应用程序逻辑。您可能会导致竞争状况,其中有尚未注册的依赖项,或者造成不必要的开销(例如,即使不需要任何查询也可以建立数据库连接)。

第二,Laravel's request lifecycle直到 所有服务提供商注册和引导完成之后,才会将当前请求转移到应用程序中。

在不完全知道要完成的业务逻辑的情况下,您至少有两个选择:

  1. 使用contextual binding来根据请求对象(例如控制器)为同一接口提供不同的实现。

  2. 使用可插入控制器中的工厂或类似促进者风格的对象,并可以根据您的首选逻辑提供适当的依赖性。