一、基础绑定 & 接口绑定
// 普通绑定
app()->bind('cach.driver',\think\cache\driver\Redis::class);
// 接口绑定
app()->bind(\app\service\SmsInterface:class,\app\service\AliyunSms::class);
// 使用
$sms = app(\app\service\SmsInterface::calss);
二、单例(singleton)
保证容器内只有一个实例(比如数据库/Redis客户端)
app()->singleton('redis',function(){
$redis = new \Redis();
$redis->connect('127.0.0.1');
return $redis;
});
// 多次获取,都是同一个对象
$redis1 = app('redis');
$redis2 = app('redis');
var_dump($redis1 === $redis2); // true
三、别名绑定
给服务起多个名字,方便调用
app()->bind('sms.aliyun', \app\service\AliyunSms::class);
app()->bind('sms.tencent', \app\service\TencentSms::class);
$sms1 = app('sms.aliyun');
$sms2 = app('sms.tencent');
四、延迟加载(Lazy Binding)
闭包绑定,只有第一次调用时才会创建实例。
app()->bind('big.service', function() {
return new \app\service\BigService();
});
五、参数覆盖 / 动态依赖注入
在 make时传入参数覆盖构造方法。
$userService = app()->make(\app\service\UserService::class, [
'uid' => 1001
]);
六、ServiceProvider(服务提供者)
把复杂注册逻辑放在Provider类里
app/provider/SmsServiceProvider.php
<?php
namespace app\provider;
use think\Service;
use app\service\SmsInterface;
use app\service\AliyunSms;
class SmsServiceProvider extends Service
{
public function register()
{
// 注册服务
$this->app->bind(SmsInterface::class, AliyunSms::class);
}
public function boot()
{
// 启动时执行逻辑,例如监听事件
// Event::listen('sms.send', ...);
}
}
config/app.php
'providers' => [
app\provider\SmsServiceProvider::class,
],
七、事件驱动 + 容器结合
事件监听器可通过容器解析依赖
<?php
use think\facade\Event;
// 注册监听
Event::listen('sms.send', function($data) {
$logger = app('log');
$logger->info("短信发送: " . json_encode($data));
});
// 触发事件
event('sms.send', ['phone'=>'13800001111', 'msg'=>'验证码1234']);
八、自定义Facade(门面)
让容器服务可以用静态方法调用
app/facade/Sms.php
<?php
namespace app\facade;
use think\Facade;
class Sms extends Facade {
protected static function getFacadeClass()
{
return \app\service\SmsInterface::class;
}
}
使用
use app\facade\Sms;
Sms::send('13800001111', '验证码:1234');
总结
TP6容器的高级用法主要有以下几种:
- 绑定方式多样:普通、接口、别名、闭包、单例
- 灵活注入:动态传参、延迟加载
- 扩展机制:ServiceProvider管理复杂逻辑
- 事件 & Facade:让解耦更彻底,调用更优雅