需运行 php think service:discover 生成 runtime/service.php,否则服务提供者不加载;执行后检查该文件是否存在且非空,开头应有合法PHP代码。

service.php 缓存没生成或被跳过
ThinkPHP 不会自动读取 runtime/service.php,它只在执行 php think service:discover 后才写入该文件;如果没运行过这条命令,或执行时出错,service.php 就是空的或根本不存在——此时服务提供者完全不会加载。
- 进入项目根目录(确保有
think可执行脚本),运行php think service:discover - 检查
runtime/service.php是否存在且内容非空,开头应有1];这类结构 - 若报错
Class not found,说明composer.json中声明的提供者类路径错误,或composer dump-autoload没执行
composer.json 的 extra.think.providers 写错了
ThinkPHP 只扫描 vendor/ 下各包的 composer.json 中 extra.think.providers 字段,漏掉字段、路径拼错、大小写不一致,都会导致服务提供者“隐身”。
- 确认自定义包的
composer.json中有合法的"extra": {"think": {"providers": ["Vendor\Package\ServiceProvider"]}} - 反斜杠必须用双反斜杠
\或正斜杠/(JSON 中单反斜杠非法) - 类名必须与实际 PHP 文件路径严格一致:如文件在
src/ServiceProvider.php,命名空间是VendorPackage,就不能写成vendorpackageServiceProvider
服务提供者类没实现 register() 或 bind 失败
即使缓存生成了、类也加载了,如果 register() 方法里没调用 $this->app->bind() 或 $this->app->singleton(),容器里依然没有你的服务实例。
将 .eth 名称解析为以太坊地址,反之亦然。适用于用户提供 .eth 名称(如“发送给 vitalik.eth”)、显示地址时展示 ENS 名称、查询 ENS 档案,或帮助注册、续期、管理 .eth 名称。
- 打开你的服务提供者类,确认
register()方法内有类似$this->app->bind('MyService', MyService::class);的绑定逻辑 - 不要只写
new MyService()而不绑定;也不要在register()里 throw 异常或 exit,否则整个发现流程中断 - 若服务依赖其他类(如数据库连接),确保那些类已注册且可解析,否则
bind会静默失败
开发期 config/app.php 的 providers 数组被忽略
很多人把服务提供者类名直接加到 config/app.php 的 providers 数组里,以为能绕过 discover 流程——但 ThinkPHP 6+ 已废弃该方式,只有通过 service:discover 生成的缓存才生效。
- 删掉
config/app.php中'providers' => [...]里手动添加的自定义服务提供者项 - 保留官方框架自带的提供者(如
thinkserviceProvider),它们走的是另一套硬编码加载逻辑 - 若需临时调试,可在
register()开头加dump('loaded');并访问接口验证是否真被调用
服务提供者失效最隐蔽的一点是:没有任何报错,service.php 看似存在,但里面没你的类名——因为 service:discover 扫描时跳过了那个包,可能只是 composer.json 多了个逗号,或路径用了中文全角符号。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










