make()是按需构造,get()是查表取值;make()可反射创建新实例,默认不复用,get()仅查找$instances或$bindings中已存项,不自动构造,未注册则失败。

make() 和 get() 都能取实例,但行为完全不同
二者表面都返回对象,但 make() 是“按需构造”,get() 是“查表取值”。不理解这点,容易在单例管理、依赖注入或调试时踩坑。
make() 每次都可能新建实例,除非显式设为单例
make() 的核心逻辑是:先查 $instances(已缓存的单例),再查 $bindings(绑定规则),最后用反射创建新实例。它默认不复用,即使类已存在绑定,只要没标记为单例,就每次 new。
- 调用
App::make('app\service\UserService')→ 若未绑定或未 singleton,则走反射构造,可能触发多次__construct() - 想强制复用?得提前
App::singleton('app\service\UserService', UserService::class) - 传
true作第三个参数($newInstance = true)会跳过缓存,一定新建 —— 这在测试隔离场景有用,但线上慎用
get() 只查已注册/已实例化的项,不自动构造
get() 不做反射、不解析依赖、不 fallback 创建。它只在 $instances 或 $bindings 中找对应 key,找不到就抛异常或返回 null(取决于版本和上下文)。
-
App::get('cache')成功,是因为框架启动时已把think\Cache绑定并实例化进$instances -
App::get('app\service\UserService')几乎必失败 —— 除非你手动bind()了字符串标识,或提前make()过一次且没设$newInstance = true - 别指望
get()像 Laravel 的app()那样兜底调用make();ThinkPHP 的get()就是纯查找
别名、绑定和类路径错位是常见失败原因
报 Class not found 或返回 null,90% 不是容器 bug,而是注册链断了:类没被加载、绑定名对不上、或用了未声明的别名。
- 确认
class_exists('app\service\UserService')返回true,否则先跑php think optimize:autoload - 绑定时用
App::bind('user_service', UserService::class),后续才能用App::make('user_service')—— 直接传完整类名字符串也行,但必须确保命名空间与文件路径 100% 匹配(PSR-4) -
get()查的是 key,不是类名:你bind('cache', Cache::class),就得get('cache'),不能get(Cache::class)
实际开发中,make() 是日常主力,get() 更适合取框架预置服务(如 request、config)或你自己明确 singleton() 过的对象;混淆二者,最容易在中间件或命令行指令里遇到“对象状态不一致”问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











