服务提供者
定义
服务提供者就是,当前应用需要哪些服务/组件,我们就在服务提供者里面定义哪些服务/组件,方便在程序里面直接使用,解决了类与类之间的耦合
存放位置
可以在任意位置建立服务提供者,我们推荐在 /common/provider 目录下新建服务提供者类,服务提供者类必须继承Timo\Support\ServiceProvider, 我们只需在类的register方法里面注册服务即可,看下面的例子 服务提供者可以是多个,我们可以使用服务提供者下面的$container(服务容器实例)属性来注册服务
新建服务提供者
创建一个空的服务提供者CommonProvider,意思就是没有注册任何一个服务,路径:
/common/provider/CommonProvider
<?php
namespace common\provider;
class CommonProvider extends ServiceProvider
{
public function register()
{
}
}
注册服务
注册服务只需在register方法里面注册服务即可,注册方式有很多种
方式一,普通注册,通过get获取服务时,获取到的都是全新服务实例
$this->container->bind();
方式二,单例模式注册,通过get获取服务时,获取到的都是同一个服务器实例
$this->container->singleton();
方式三,注册一个服务器实例
$this->container->instance();
举例说明
<?php
namespace common\provider;
use lib\markdown\Markdown;
use Timo\Support\ServiceProvider;
class CommonProvider extends ServiceProvider
{
public function register()
{
$this->container->bind([Car::class => 'car'], function() {
return new Car();
});
$this->container->singleton('markdown', Markdown::class);
$this->container->singleton('markdown', 'lib\markdown\Markdown');
$this->bind(['lib\pay\Client' => 'pay'], function($container) {
$car = $container->get('car');
return new Client($car);
});
}
}
上面我们注册了一个名为car的服务,并且是以单例的模式注册的,可以在register方法里面注册多个服务
服务别名
namespace common\provider;
use lib\markdown\Markdown;
use Timo\Support\ServiceProvider;
class CommonProvider extends ServiceProvider
{
public function register()
{
//说明 Markdown::class 等于 'lib\markdown\Markdown' , 服务别名就是markdown
$this->container->singleton([Markdown::class => 'markdown'], Markdown::class);
}
}
注册服务提供者
我们要告诉框架有哪些服务提供者
可以在配置文件中providers项定义服务提供者,可注册多个
'providers' => [
app\provider\CommonProvider::class,
app\provider\PayProvider::class,
app\provider\Ossprovider::class
]
怎样获取服务容器实例
我们要在其它类里面使用服务容器,该怎么获取呢?
$container = App::container();
比如,我们要在控制器里面使用,我们可以放到所有控制器的基类里面,比如Base、Common控制器
namespace app\web\controller;
use Timo\Core\Controller;
class Base extends Controller
{
protected $container;
public function __construct()
{
parent::__construct();
$this->container = App::container();
}
}
然后,我们就可以在其它控制器里面方便的使用了
php
namespace app\web\controller;
use app\web\model\DocumentModel;
use lib\markdown\Markdown;
use Timo\Core\Exception;
use Timo\Core\Request;
class Document extends Common
{
/**
* 文档详情页
*
* @param int $id
* @return string
* @throws Exception
*/
public function show($id = 0)
{
$id = (int) $id;
if ($id <= 0) {
throw new Exception('文档ID不能小于零');
}
//获取文档标题
$document = (new DocumentModel())->getDocument($id);
if (!$document) {
throw new Exception('文档'.$id.'不存在');
}
//获取文档内容
/**
* @var $markdown Markdown
*/
$markdown = $this->container->get('markdown');
$doc_html = $markdown->makeHtmlFragment('document', $id, false);
$this->assign('title', $document['title']);
$this->assign('doc', $doc_html);
return $this->render();
}
}