Laravel绑定的用途和目的是什么?

时间:2018-03-18 13:58:11

标签: php laravel

我无法理解Laravel的绑定系统。我知道依赖注入是什么意思。它甚至可以在没有那种奇怪的"绑定的情况下工作,对吧?我在文档中看到,绑定可以返回一个新对象。为什么以及何时使用它?请解释不是很复杂,因为我已经阅读了文档,我无法理解该绑定的用途和目的。感谢。

1 个答案:

答案 0 :(得分:11)

  

即使没有那种奇怪的“绑定”它也可以工作,对吗?

不是真的。当然,如果所需的依赖项很容易实例化,它可以正常工作。假设您在Foo目录中存储了这个简单的类app

<?php

namespace App;

class Foo
{
    public function hello()
    {
        return 'Hello World';
    }
}

您可以键入提示此类,而不首先在容器中绑定它。 Laravel仍然可以解决这个课程。假设您在路线中将其类型暗示:

Route::get('/foo', function (App\Foo $foo) {
    return $foo->hello(); // Hello World
});

我们甚至可以走得更远,让我们说这个Foo类需要另一个简单的类Bar。我们的Bar课程如下:

<?php

namespace App;

class Bar
{
    public function hello()
    {
        return 'bar';
    }
}

我们的Foo课程现在看起来像这样:

<?php

namespace App;

class Foo
{
    public function __construct(Bar $bar)
    {
        $this->bar = $bar;
    }

    public function hello()
    {
        return $this->bar->hello();
    }
}

Laravel现在可以解决类型提示的Foo课吗?是! Laravel仍然可以解决此Foo课程。

现在,当我们的Foo类需要稍微复杂的需要配置的依赖项时,问题就会出现。想象一下,我们的Foo类只需要我们的应用程序的名称。当然,您只需在类的方法中使用config('app.name'),但可以想象这可能是需要配置数组实例化的HTTP客户端。

<?php

namespace App;

class Foo
{
    public function __construct($appName)
    {
        $this->appName = $appName;
    }

    public function hello()
    {
        return "Hello {$this->appName}";
    }
}

Laravel现在可以解决这个课吗?不。 Service Container救援!您可以通过将它绑定在服务容器中来教Laravel如何解析此Foo类。您可以在register文件的app\Providers\AppServiceProvider.php方法中定义绑定:

public function register()
{
    $this->app->bind(\App\Foo::class, function ($app) {
        // Pass the application name
        return new \App\Foo($app->config['app.name']);
    });
}

有时,您不希望创建多个实例。就像我们的Foo类一样,这种类不需要多个实例。在这种情况下,我们可以用单例方法绑定它。

$this->app->singleton(\App\Foo::class, function ($app) {
    return new \App\Foo($app->config['app.name']);
});

更重要的用法

但是这个服务容器的更重要的用途是我们可以将接口绑定到它的实现。假设我们使用PaymentProcessorInterface pay方法:

<?php

namespace App;

interface PaymentProcessorInterface
{
    public function pay();
}

然后我们实现了这个名为StripeProcessor的接口:

<?php

namespace App;

class StripeProcessor implements PaymentProcessorInterface
{
    public function pay()
    {
        return 'pay with stripe';
    }
}

使用服务容器,我们可以将PaymentProcessorInterface绑定到StripeProcessor类:

$this->app->bind(\App\PaymentProcessorInterface::class, function () {
    return new \App\StripeProcessor();
});

然后我们可以在代码中输入提示PaymentProcessorInterface

Route::get('/pay', function (App\PaymentProcessorInterface $paymentProcessor) {
    return $paymentProcessor->pay(); // pay with stripe
});

这样我们就可以轻松交换PaymentProcessorInterface实现。假设我们想要将支付处理器更改为Paypal,那么我们就有PaypalProcessor类。

<?php

namespace App;

class PaypalProcessor implements PaymentProcessorInterface
{
    public function pay()
    {
        return 'pay with paypal';
    }
}

我们所要做的就是更新绑定:

$this->app->bind(\App\PaymentProcessorInterface::class, function () {
    return new \App\PaypalProcessor();
});

希望这会给你一些想法。