bind注册创建规则,每次make都新建实例;instance直接存入现成对象,后续调用均返回同一实例。前者适用于无状态类,后者适用于需全局复用的已初始化对象。

Laravel 6 的服务容器中,bind 和 instance 看似都是“把东西塞进容器”,但本质完全不同:bind 是注册创建规则,instance 是直接塞一个现成的对象。用错会导致状态混乱、连接泄漏或测试不可靠。
bind 是定义“怎么造”,每次调用都新建实例
它告诉容器:“下次要这个类/接口时,请按这个方式 new 一个”。不保存结果,只存逻辑。
每次
app()->make()或依赖注入时,都会执行绑定的闭包(或反射构造),生成全新对象适合无状态、轻量、需隔离的类,比如表单请求类、DTO、策略类
-
示例:
$this->app->bind('App\Services\Formatter', function ($app) { return new JsonFormatter(); // 每次都 new 一个新的 }); 注意:如果闭包里手动
new DatabaseConnection(),又没做连接复用,高并发下会快速耗尽数据库连接池
instance 是直接“塞成品”,跳过所有构造逻辑
它不关心怎么创建,只把一个已经初始化好的对象硬塞进容器,并让后续所有解析都返回它。
容器不会调用构造函数,不会解析依赖,也不会执行任何闭包
适用于你已手动初始化好、且必须复用该实例的场景,比如第三方 SDK 客户端、测试 Mock 对象
-
示例:
$client = new GuzzleHttp\Client(['timeout' => 5]); $this->app->instance('GuzzleHttp\Client', $client); // 后续 app(Client::class) 永远返回这个$client -
风险点:
- 若该实例内部有状态(如缓存属性、未重置的计数器),所有使用者会共享它
- 若依赖其他服务(比如
$client依赖了自定义 Handler),而这些依赖没被容器管理,就可能在测试或热更时出问题
什么时候该选哪个?
- 用
bind:你要让容器控制生命周期,希望每次都是干净新实例,或需要自动注入其构造参数 - 用
instance:你已经有完全初始化好的对象,明确要求全局复用它,且能确保它的线程安全与状态可控 - 不要用
instance替代singleton:后者由容器管理构造和依赖解析,前者绕过全部机制,调试困难、扩展性差
两者底层存储位置也不同:instance 的对象存在 $container->instances 数组里;bind 的逻辑存在 $container->bindings 中,不存实例。











