laravel 6 中无法直接调用 api 判断单例,需通过实例复用性(=== 比较)、检查 $instances 数组或查看服务提供者注册方式(singleton/bind/instance)来识别,自动解析和闭包返回固定对象不属于容器单例。

在 Laravel 6 中,服务容器本身不提供直接的 API(比如 isSingleton())来判断某个绑定是否为单例模式。但你可以通过检查容器内部状态和行为特征来可靠识别——关键不是“问容器”,而是“看它怎么工作”。
看实例是否复用(最直接有效)
单例的核心表现是:同一请求内多次解析返回**同一个对象实例**。用 === 比较即可验证:
$a = app(MyService::class);$b = app(MyService::class);var_dump($a === $b); // true → 极大概率是 singleton 绑定
注意:这个方法在当前请求生命周期内有效。如果返回 false,说明不是单例(可能是 bind() 或未注册自动解析)。
查容器的 $instances 数组(底层依据)
Laravel 容器内部用 $instances 属性缓存 singleton 实例。你可以手动访问(仅限调试/开发环境):
$container = app();$isSingleton = array_key_exists(MyService::class, $container->getInstances());
✅ 返回 true 表示该类已被解析过且结果已缓存 → 是 singleton 绑定(或曾被 instance() 注入)。
⚠️ 注意:getInstances() 是 public 方法,但依赖内部结构,不建议用于生产逻辑判断。
检查绑定类型(需知道注册位置)
如果你能定位到服务提供者中的注册代码,就可明确判断:
- 用了
$this->app->singleton(...)→ 单例 - 用了
$this->app->bind(...)→ 非单例(每次新建) - 用了
$this->app->instance(...)→ 手动注入,效果等同单例(但非容器创建)
这是最准确的方式,但需要代码可见性,不适合运行时动态判断。
避免误判的两个常见陷阱
以下情况容易让人误以为是单例,实则不是:
-
自动解析的类:没做任何绑定,直接
app(SomeClass::class)—— 它每次都会 new 一个新实例(除非你显式设为 singleton) -
闭包中返回固定对象:
bind(..., function() { return $sharedObj; })看似单例,但容器并不知道,也不会管理其生命周期,不属于容器意义上的 singleton











