TP6的服务在自定义composer包中如何使用

官方关于Service的说明文档:
https://www.kancloud.cn/manual/thinkphp6_0/1037490

做下概念说明:
Service和Provider在TP6中扮演着不同的角色。Service是用于封装特定功能的类,而Provider是用于注册和配置Service的类。

这里的Service指的是注册到容器中的一系列可以调用的类或方法(函数)。注册后的类或方法,可以直接从容器调用(即:依赖注入),例:

app(‘test’)->show();

看下是如何做到的,以下只对开发composer扩展包进行说明,写在项目目录中的可以参考官方的说明。

1.新建一个扩展包。
2.扩展包添加composer.json文件

{
    "name": "test/svs",
    "type": "library",
    "license": "MIT",
    "autoload": {
        "psr-4": {
            "Test\\Svs\\": "src/"
        }
    },
    "extra": {
        "think": {
            "services": [
                "Test\\Svs\\SvsService" # 这里必须写正确(写不正确TP也不会报错,只会让你搞不清楚为什么不生效...]         
        }
    }
}

3.新建src目录,并添加具体的服务(即:Service)文件:Test.php
这个类将被注册到容器中:

<?php

namespace Test\Svs;

class Test
{

    private $foo;

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

    public function show()
    {
        echo 'say test...';

        $this->foo->show();
    }
}

再建2个类用于测试依赖注入:

先来一个接口:

<?php

namespace Test\Svs;

interface IFoo
{
    public function show();
}

建两个类实现接口:

这个类只是实现了接口,但由于没有注册到容器,所以不能自动注入

<?php

namespace Test\Svs;

class Foo implements IFoo
{
    public function show()
    {
        echo 'say foo...';
    }
}

Bar.php,指定用来依赖注入的:

<?php

namespace Test\Svs;

class Bar implements IFoo
{
    public function show()
    {
        echo 'say bar...';
    }
}

4.新建服务注册(即:Provider)文件:SvsService.php
这个类是用来把Test注册到容器中,并可以执行启动相关操作。register()比boot()方法先执行。

<?php

namespace Test\Svs;

use think\Service;

/**
 * 定义服务类
 * 安装时将被添加到vendor/services.php中
 * 
 * @author gjw
 * @created 2023-06-29 09:35:28
 */
class SvsService extends Service
{
    /**
     * 注册
     *
     * @author gjw
     * @created 2023-06-29 09:36:22
     *
     * @return void
     */
    public function register()
    {
        echo 'SvsService::register()';
        // 注册一个类到容器
        // $this->app->bind('test', Test::class); // 实例类型是确定的可以不注册,系统能根据类型找到要注入哪个类
        $this->app->bind(IFoo::class, Bar::class); // 实例类型是不确定的,要明确指出要注入哪个类
        // 这里只做个绑定演示,个人感觉类型不确定的不要在这里进行绑定(相当于是写死了)
        // 可以在配置文件中设置绑定:app/provider.php(app/service.php虽然可以绑定,但不能指定类型--键名就是类型)
    }

    /**
     * 启动
     *
     * @author gjw
     * @created 2023-06-29 09:36:29
     *
     * @return void
     */
    public function boot()
    {
        echo 'SvsService::boot()';
        // 注册到容器的类已可以使用
        app('test')->show();
    }
}

SvsService这个类在composer.json中已配置过,所以运行composer安装或单独执行命令(php think service:discover)时,会被注册到vendor/services.php中。当程序运行时(包含command),这个文件会被加载,并运行注册和启动方法。
也就是说,composer方法注册的服务不需要添加到app/services.php即可使用。

接下来,项目任意位置都可以这样用了:
app(‘test’)->show();

或是在控制器方法上直接用作参数:

	public function index(SvsTest $t)
    {
        echo '<br>';
        $t->show();

        return view('index', array('time' => time()));
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值