Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/245.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP-Laravel依赖项注入:将参数传递给依赖项构造函数_Php_Dependency Injection - Fatal编程技术网

PHP-Laravel依赖项注入:将参数传递给依赖项构造函数

PHP-Laravel依赖项注入:将参数传递给依赖项构造函数,php,dependency-injection,Php,Dependency Injection,我正在构建一个Laravel项目,在其中一个控制器中,我在一个方法中注入了两个依赖项: public function pusherAuth(Request $request, ChannelAuth $channelAuth) { ... } 我的问题很简单:如何将参数传递给$channelAuth依赖项 目前,我正在使用一些setter来传递所需的依赖项: public function pusherAuth(Request $request, ChannelAuth $channelAu

我正在构建一个Laravel项目,在其中一个控制器中,我在一个方法中注入了两个依赖项:

public function pusherAuth(Request $request, ChannelAuth $channelAuth) { ... }
我的问题很简单:如何将参数传递给
$channelAuth
依赖项

目前,我正在使用一些setter来传递所需的依赖项:

public function pusherAuth(Request $request, ChannelAuth $channelAuth)
{
    $channelAuth
        ->setChannel($request->input('channel'))
        ->setUser(Auth::user());
这种方法的替代方案是什么


另外,代码需要可测试。

您可以创建并注册自己的服务提供商,并使用构造函数的请求参数创建对象


我不知道如何在Laravel中做到这一点,但在Symfony2中,您可以在自己的服务中注入类似RequestStack的东西。这是最好的方法,因为您有完全可测试的小型服务提供商。

多亏了我在这方面得到的帮助,我才能够回答这个问题。使用服务提供者,可以通过向构造函数传递正确的参数来初始化依赖关系。这是我创建的服务提供商:

<?php namespace App\Providers;

use Security\ChannelAuth;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;

class ChannelAuthServiceProvider extends ServiceProvider {

    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind('Bloom\Security\ChannelAuthInterface', function()
        {
            $request = $this->app->make(Request::class);
            $guard   = $this->app->make(Guard::class);

            return new ChannelAuth($request->input('channel_name'), $guard->user());
        });
    }
}

如果希望通过类型提示注入依赖项,则应使用工厂模式

public function pusherAuth(Request $request, ChannelAuthFactory $channelAuthFactory)
{
    $channelAuth = $channelAuthFactory->from($request->input('channel'), $request->user());
在解析如下依赖关系时,可以传递参数(作为字符串索引数组):

<?php namespace App\Providers;

use Security\ChannelAuth;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Support\ServiceProvider;

class ChannelAuthServiceProvider extends ServiceProvider {

    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind('Bloom\Security\ChannelAuthInterface', function($params)
        {
            $channelName = $params['channelName'];
            $guard   = $this->app->make(Guard::class);

            return new ChannelAuth($channelName, $guard->user());
        });
    }
}

但是如果您的输入没有设置“channel\u name”怎么办?在您有机会验证输入之前,可能会调用此代码。@omarjebari我想这取决于您在哪里注入
Bloom\Security\ChannelAuthInterface
,在我的情况下,是在输入验证之后。如果您仍然必须手动实例化依赖项,则它似乎会破坏依赖项注入点。工厂模式与依赖项注入并不矛盾。但是因为channelauth使用全局变量,我同意这种方式更好
public function pusherAuth()
{
    $channelAuth = app()->makeWith('Bloom\Security\ChannelAuthInterface', [
        'channelName' => $request->input('channel_name')
    ]);
    // ... use $channelAuth ...
}