laravel自动解析无参或参数可解析的普通类,无需显式绑定;需用bind()而非singleton()注册无状态类;接口使用必须显式绑定实现;所有绑定须在register()中完成。

直接用 bind() 或 singleton() 注册类名即可,不需要写闭包,也不用管构造函数——Laravel 会自动 new 出来。
普通类自动解析是默认行为
只要你的类没有构造函数参数,或参数全是容器能自动解析的类型(比如 Request、LoggerInterface 等已绑定项),Laravel 就能直接实例化它,无需显式绑定。
- 例如:
class Formatter { public function format($data) { return json_encode($data); } } - 直接
app()->make(Formatter::class)就能拿到新实例,不用提前 bind - 原理是服务容器通过 PHP 反射调用
new Formatter,不依赖构造逻辑
显式绑定推荐用 bind(),不是 singleton()
无状态、轻量、每次需要干净实例的普通类,应使用 bind()。它保证每次 make() 都新建对象,避免状态残留。
- 在
AppServiceProvider@register()中写:$this->app->bind(Formatter::class, Formatter::class); - 等价写法(更清晰):
$this->app->bind(Formatter::class, function () { return new Formatter(); }); - 别用
singleton()——除非你明确要复用同一个实例(比如带内部计数器的工具类)
接口绑定时必须显式声明
如果你的普通类实现了某个接口,而你想通过接口获取它,就必须显式绑定接口到实现类。
- 比如:
interface Exporter { public function export($data); }和class JsonExporter implements Exporter - 必须写:
$this->app->bind(Exporter::class, JsonExporter::class); - 否则
app()->make(Exporter::class)会报Target [Exporter] is not instantiable
别在 boot() 里绑定,register() 才是正确时机
所有绑定操作必须放在服务提供者的 register() 方法中。boot() 阶段容器已经开始解析依赖,此时绑定可能被忽略,尤其在队列、命令行或测试中极易出错。
- 确认
config/app.php的providers数组包含你的服务提供者 - 不要图省事写
$this->app->bind(...)在boot()里,即使本地跑得通,CI 环境大概率失败











