php Laravel -我需要为每个服务容器/定制类提供商吗?

sd2nnvve  于 2023-08-02  发布在  PHP
关注(0)|答案(1)|浏览(106)

服务容器/提供者的概念可能比我想象的要简单得多,但是在阅读了几个小时之后,我仍然没有完全理解它。
我在app/Library中创建了一个简单的DateFormat类。在\config\app.php中为它创建别名后,我可以立即在任何控制器或刀片模板中使用它。

<?php namespace App\Library;

class DateFormat {

    public static function getDate($timestamp){
      // processing the timestamp      
    }

}

字符串
我刚刚创建了一个服务容器吗?如果是,我是否还需要创建一个服务提供商?怎么会有装订?
我真的很感激你能在这个问题上给我点光。
谢啦,谢啦

tyu7yeag

tyu7yeag1#

不。你创建的只是类的别名。服务提供者是绑定特定类的一种方式,通常与Facade结合使用。
别名只是一种使用类的方便方法,而不必每次都导入整个命名空间的类。
例如,如果你有一个类\My\Very\Long\Class\Adapter,你可以在config/app.php中别名它:

// config/app.php
<?php
'aliases' => [
    // a bunch of aliases
    'MyAdapter' => My\Very\Long\Class\Adapter::class,
]

字符串
现在你可以做:

<?php

new MyAdapter();
...


而不是:

<?php

use My\Very\Long\Class\Adapter;
...
new Adapter();
...


当您想要解决依赖关系时,通常使用服务提供者,最常见的是通过注入。当要解析的类需要将参数传递到构造函数中或每次都有通用设置时,这会很有帮助。您可以在提供程序中执行所有设置。
下面是一个场景:
您有一个您想要与之交互的API。我们就叫它SuperApi。SuperAPI的文档说,要创建SuperApi类的示例,您必须执行以下操作:

<?php
// Some method (a controller or something)
public function index()
{
    $superApi = new \SuperApi\Connector($key, $secret);
    return $superApi->getCustomers();
}


现在,每当你想创建一个这样的示例时,你都必须做同样的设置(或者将它抽象为某个类,但事实是你需要向构造函数传递一个$key$secret)。
如果你要为这个Connector类创建一个别名,它可能是:

// config/app.php
<?php
'aliases' => [
    // a bunch of aliases
    'SuperApi' => SuperApi\Connector::class,
]


所以,有了这个别名,你现在可以这样做:

<?php

// Some method (a controller or something)
public function index()
{
    $superApi = new SuperApi($key, $secret);
    return $superApi->getCustomers();
}


但是你看,即使有别名,你仍然需要传递$key$secret
这是服务提供商可以提供帮助的地方。

// app/Providers/SuperApiProvider.php
<?php

namespace App\Providers;

use SuperApi\Connector;
use Illuminate\Support\ServiceProvider;

class SuperApiProvider extends ServiceProvider
{
    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind('superApiConnector', function ($app) {
            return new ApiConnector($app['config']->get('super-api.key'), $app['config']->get('super-api.secret'));
        });
    }
}

// app/Providers/SuperApi.php (the Facade)
<?php

namespace App\Providers;

use Illuminate\Support\Facades\Facade;

class SuperApi extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'superApiConnector';
    }
}

// config/super-api.config
<?php

return [
    'key' => env('SUPER_API_KEY'),
    'secret' => env('SUPER_API_SECRET'),
];

// config/app.php
<?php
'providers' => [
    // a bunch of providers
    App\Providers\SuperApiProvider::class,
]


请注意,在提供程序中绑定的字符串('superApiConnector')与从facade返回的字符串相同,facade的类名是实际调用绑定类的方式,在本例中为SuperApi
现在,当你想使用SuperApi\Connector类时,你可以这样做:

<?php

// Some method (a controller or something)
public function index()
{
    return SuperApi::getCustomers();
}


正如我上面所说的,当你想注入它并让Laravel's IoC Container自动解析注入的类时,提供程序真正有用的地方:

<?php
// Some method (a controller or something)
public function index(SuperApi $api)
{
    return $api->getCustomers();
}


需要明确的是,您不需要服务提供者来利用依赖注入。只要类可以被应用程序解析,它就可以被注入。这意味着无论您注入的类的构造函数采用什么参数都需要是可自动解析的。

相关问题