Laravel - 我的每个服务容器/自定义 类 都需要一个服务提供商吗?
Laravel - do I need a service provider for each of my service containers / custom classes?
服务容器/提供者的概念可能比我想象的要简单得多,但经过几个小时的阅读,我仍然完全不明白。
我在 app/Library
中创建了一个简单的 DateFormat
class。在 \config\app.php
中为其创建别名后,我可以立即在任何控制器或 blade 模板中使用它。
<?php namespace App\Library;
class DateFormat {
public static function getDate($timestamp){
// processing the timestamp
}
}
我刚刚创建了一个服务容器吗?如果是,我还需要创建一个服务提供商吗?图片中的绑定在哪里?
我非常希望能对这个主题有所了解。
谢谢
没有。您创建的只是 class 的别名。服务提供商是绑定特定 class 的一种方式,通常与 Facade 结合使用。
别名只是一种使用 class 的便捷方式,无需每次都导入整个命名空间 class。
例如,如果您有一个 class \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();
...
当您想要解决依赖关系时,通常会使用服务提供者,最常见的是通过注入。当您要解析的 class 需要将参数传递给构造函数或每次都具有通用设置时,这会很有帮助。您可以在提供程序中执行所有设置。
这是一个场景:
您有一个 API 想要与之互动。我们称之为 SuperApi。 SuperAPI 的文档说要创建 SuperApi class 的实例,您必须执行以下操作:
<?php
// Some method (a controller or something)
public function index()
{
$superApi = new \SuperApi\Connector($key, $secret);
return $superApi->getCustomers();
}
现在,每次你想创建它的实例时,你都必须进行相同的设置(或将其抽象为某些 class,但事实仍然是你需要传递一个 $key
和 $secret
到构造函数)。
如果您要为此 Connector
class 创建一个别名,可能会是:
// 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'
) 中绑定到的字符串与您从外观 return 中绑定的字符串相同,外观的 class 名称就是您的方式实际上会调用绑定 class,在本例中为 SuperApi
.
现在,当您想要使用 SuperApi\Connector
class 时,您可以这样做:
<?php
// Some method (a controller or something)
public function index()
{
return SuperApi::getCustomers();
}
正如我上面所说,提供程序真正派上用场的地方是当你想要注入它并让 Laravel's IoC Container 自动解析注入的 class:
<?php
// Some method (a controller or something)
public function index(SuperApi $api)
{
return $api->getCustomers();
}
需要说明的是,您不需要服务提供商来利用依赖注入。只要 class 可以被应用程序解析,它就可以被注入。这意味着您要注入的 class 构造函数的任何参数都需要自动解析。
服务容器/提供者的概念可能比我想象的要简单得多,但经过几个小时的阅读,我仍然完全不明白。
我在 app/Library
中创建了一个简单的 DateFormat
class。在 \config\app.php
中为其创建别名后,我可以立即在任何控制器或 blade 模板中使用它。
<?php namespace App\Library;
class DateFormat {
public static function getDate($timestamp){
// processing the timestamp
}
}
我刚刚创建了一个服务容器吗?如果是,我还需要创建一个服务提供商吗?图片中的绑定在哪里?
我非常希望能对这个主题有所了解。
谢谢
没有。您创建的只是 class 的别名。服务提供商是绑定特定 class 的一种方式,通常与 Facade 结合使用。
别名只是一种使用 class 的便捷方式,无需每次都导入整个命名空间 class。
例如,如果您有一个 class \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();
...
当您想要解决依赖关系时,通常会使用服务提供者,最常见的是通过注入。当您要解析的 class 需要将参数传递给构造函数或每次都具有通用设置时,这会很有帮助。您可以在提供程序中执行所有设置。
这是一个场景:
您有一个 API 想要与之互动。我们称之为 SuperApi。 SuperAPI 的文档说要创建 SuperApi class 的实例,您必须执行以下操作:
<?php
// Some method (a controller or something)
public function index()
{
$superApi = new \SuperApi\Connector($key, $secret);
return $superApi->getCustomers();
}
现在,每次你想创建它的实例时,你都必须进行相同的设置(或将其抽象为某些 class,但事实仍然是你需要传递一个 $key
和 $secret
到构造函数)。
如果您要为此 Connector
class 创建一个别名,可能会是:
// 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'
) 中绑定到的字符串与您从外观 return 中绑定的字符串相同,外观的 class 名称就是您的方式实际上会调用绑定 class,在本例中为 SuperApi
.
现在,当您想要使用 SuperApi\Connector
class 时,您可以这样做:
<?php
// Some method (a controller or something)
public function index()
{
return SuperApi::getCustomers();
}
正如我上面所说,提供程序真正派上用场的地方是当你想要注入它并让 Laravel's IoC Container 自动解析注入的 class:
<?php
// Some method (a controller or something)
public function index(SuperApi $api)
{
return $api->getCustomers();
}
需要说明的是,您不需要服务提供商来利用依赖注入。只要 class 可以被应用程序解析,它就可以被注入。这意味着您要注入的 class 构造函数的任何参数都需要自动解析。