Laravel绑定的用途和目的是什么? [英] What is a usage and purpose of Laravel's binding?

查看:59
本文介绍了Laravel绑定的用途和目的是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不了解Laravel的绑定系统.我知道依赖注入是什么意思.而且即使没有怪异的绑定"也可以正常工作,对吗?我在文档中看到,绑定可以返回一个新对象.为什么和何时必须使用它?请解释的不是很复杂,因为我已经阅读了文档并且无法理解该绑定的用途和目的.谢谢.

I cannot understand a point of Laravel's binding system. I know what does dependency injection mean. And it can work even without that weird "bindings", right? I saw in documentation, that binding can return a new object. Why and when I have to use that? Please, explain not very complicated, because I've read documentation and I could not understand the use and the purpose of that bindings. Thanks.

推荐答案

即使没有怪异的绑定",它也可以工作,对吧?

And it can work even without that weird "bindings", right?

并非如此.如果所需的依赖关系易于实例化,那么可以肯定它可以正常工作.假设您有一个简单的类 Foo 存储在 app 目录中:

Not really. Sure it can work just fine if the required dependencies are simple to instantiate. Let's say you have this simple class Foo stored in app directory:

<?php

namespace App;

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

您可以键入提示类,而无需先在容器中将其绑定.Laravel仍然可以解决此类问题.假设您在路线中输入了这样的提示:

You can type hinted this class without binding it first in the container. Laravel will still be able to resolve this class. Let's say you type-hinted it like this in the routes:

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

我们甚至可以走得更远,比如说这个 Foo 类需要另一个简单的类 Bar .我们的 Bar 类如下所示:

We can even go further, let's say this Foo class required another simple class Bar. Our Bar class looks like this:

<?php

namespace App;

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

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

And our Foo class looks like this now:

<?php

namespace App;

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

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

Laravel现在能够解析带有类型提示的 Foo 类吗?是的!Laravel仍然可以解析此 Foo 类.

Will Laravel be able to resolve the type-hinted Foo class now? YES! Laravel will still be able to resolve this Foo class.

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

Now the issue will come in when our Foo class needs slightly more complex dependencies that need to be configured. Imagine that our Foo class simply need the name of our application. Sure you can simply use config('app.name') within the class's method, but imagine that this can be an HTTP client that requires a configuration array to instantiate.

<?php

namespace App;

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

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

Laravel现在可以解决此类问题吗?不.服务容器来进行救援!您可以教Laravel如何通过将其绑定在服务容器中来解析此 Foo 类.您可以在 app \ Providers \ AppServiceProvider.php 文件的 register 方法内定义绑定:

Will Laravel be able to solve this class now? NOPE. Service Container to the rescue! You can teach Laravel how to resolve this Foo class by binding it in service container. You can define the binding within the register method on app\Providers\AppServiceProvider.php file:

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

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

And sometimes, you don't want multiple instances to be created. Like our Foo class for instance, there's no need for multiple instances for this kind of class. In this case, we can bind it with singleton method.

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

更多重要用法

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

But the more important usage of this service container is that we can bind an interface to it's implementation. Let's say we have this PaymentProcessorInterface with pay method:

<?php

namespace App;

interface PaymentProcessorInterface
{
    public function pay();
}

然后我们将实现名为 StripeProcessor 的该接口的实现:

Then we have the implementation of this interface named StripeProcessor:

<?php

namespace App;

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

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

With service container, we can bind the PaymentProcessorInterface to StripeProcessor class:

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

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

We can then type-hinted PaymentProcessorInterface within our code:

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

这样,我们可以轻松地交换 PaymentProcessorInterface 实现.假设我们要将付款处理程序更改为Paypal,那么我们有这个 PaypalProcessor 类.

This way we can easily swap the PaymentProcessorInterface implementation. Let's say we want to change the payment processor to Paypal then we have this PaypalProcessor class.

<?php

namespace App;

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

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

All we have to do is update the binding:

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

希望这会给您一些想法.

Hope this gives you some ideas.

这篇关于Laravel绑定的用途和目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆