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

And*_* H. 7 php laravel

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

Ris*_*ana 23

它甚至可以在没有那种奇怪的"绑定"的情况下工作,对吧?

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

<?php

namespace App;

class Foo
{
    public function hello()
    {
        return 'Hello World';
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以键入提示此类,而不首先在容器中绑定它.Laravel仍然可以解决这个课程.让我们说你在路线中这样打字:

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

我们甚至可以走得更远,让我们说这Foo堂课需要另一个简单的课程Bar.我们Bar班看起来像这样:

<?php

namespace App;

class Bar
{
    public function hello()
    {
        return 'bar';
    }
}
Run Code Online (Sandbox Code Playgroud)

我们Foo班现在看起来像这样:

<?php

namespace App;

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

    public function hello()
    {
        return $this->bar->hello();
    }
}
Run Code Online (Sandbox Code Playgroud)

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}";
    }
}
Run Code Online (Sandbox Code Playgroud)

Laravel现在可以解决这个课吗?不.服务集装箱救援!您可以Foo通过将它绑定在服务容器中来教Laravel如何解析此类.您可以registerapp\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']);
    });
}
Run Code Online (Sandbox Code Playgroud)

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

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

更重要的用法

但是这个服务容器的更重要的用途是我们可以将接口绑定到它的实现.比方说,我们有这个PaymentProcessorInterfacepay方法:

<?php

namespace App;

interface PaymentProcessorInterface
{
    public function pay();
}
Run Code Online (Sandbox Code Playgroud)

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

<?php

namespace App;

class StripeProcessor implements PaymentProcessorInterface
{
    public function pay()
    {
        return 'pay with stripe';
    }
}
Run Code Online (Sandbox Code Playgroud)

使用服务容器,我们可以绑定PaymentProcessorInterfaceStripeProcessor类:

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

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

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

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

<?php

namespace App;

class PaypalProcessor implements PaymentProcessorInterface
{
    public function pay()
    {
        return 'pay with paypal';
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

希望这会给你一些想法.

  • 官方文档应该写像你这样的人。杰出的! (3认同)