我完全无法理解拉维尔的约束系统.我知道依赖注入是什么意思.即使没有那种奇怪的"绑定",它也可以工作,对吗?我在文档中看到,绑定可以返回一个新对象.为什么以及何时我必须使用它?请解释一下,不要太复杂,因为我读过文档,无法理解绑定的用途和目的.谢谢

推荐答案

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

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';
    }
}

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
});

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个班级现在看起来是这样的:

<?php

namespace App;

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

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

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

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}";
    }
}

拉威尔现在能解决这门课吗?不是的.Service Container人出手相救!您可以通过将这个Foo类绑定到服务容器中来教Laravel如何解析它.您可以在app\Providers\AppServiceProvider.php文件的register方法内定义绑定:

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

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']);
});

More Important Usage

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();
}

Then we have the implementation of this interface named StripeProcessor:

<?php

namespace App;

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

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

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

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类.

<?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();
});

希望这能给你一些 idea .

Laravel相关问答推荐

我是否需要/是否可以从控制器运行LARLAVEL备份?

Laravel 联合和分页

如何将用户对象绑定到中间件中的请求

在 apache docker 容器中运行虚拟主机

Eager加载:在具有eloquent关系的枢轴上使用`with`

合并两个 Eloquent 集合并删除所有重复项.

我怎样才能了解更多关于我的 Laravel 排队作业(job)失败的原因?

在 Laravel 中下载后如何重定向?

使用 vue-router 更改路由时中止所有 Axios 请求

Laravel 5 - Php artisan语法错误

Laravel 随机排序

在 Laravel 容器中覆盖单例

WhereNotExists Laravel Eloquent

Laravel 搜索关系

Laravel Eloquent 多态一对一?

laravel 队列 - 同步驱动程序如何工作?它是在单独的进程/线程还是主执行线程中执行?

向 Laravel 重定向添加一个锚点

Laravel Nova 显示用户友好的资源名称

在 Laravel 中翻译特定语言

有没有办法让表名自动添加到 Eloquent 查询方法中?