使用league/container示例代码触发TypeError,请求排查问题原因
问题分析与解决:League Container 构造函数参数类型错误
问题根源
你当前代码中,$container->add('foobar', FooBar::class)->addArgument(Bar::class)这一行的addArgument(Bar::class),传递的是字符串形式的类名,而非容器中已注册的Bar实例。容器实例化FooBar时,直接将该字符串传入构造函数,但FooBar的构造函数要求接收Bar类型的对象,因此触发类型错误。
而当你直接注册$container->add(Bar::class)时,容器会通过**自动解析(auto-wiring)**识别FooBar依赖的Bar类型,自动创建并注入对应实例,所以不会报错。
修复方案
有两种可行的解决方式:
方式1:引用容器服务标识符
如果你要基于已注册的bar标识符注入实例,直接传递标识符即可,容器会自动解析对应的服务:
require __DIR__.'/../vendor/autoload.php'; use App\Service\FooBar; use App\Service\Bar; $container = new \League\Container\Container(); // 先注册Bar服务 $container->add('bar', Bar::class); // 注册FooBar时,引用已注册的'bar'服务作为参数 $container->add('foobar', FooBar::class)->addArgument('bar'); $foo = $container->get('foobar');
方式2:启用自动解析(推荐)
League Container支持自动解析依赖,无需手动添加参数,只需确保容器能识别所需服务:
require __DIR__.'/../vendor/autoload.php'; use App\Service\FooBar; use App\Service\Bar; $container = new \League\Container\Container(); // 启用反射容器实现自动解析 $container->delegate(new \League\Container\ReflectionContainer()); // 注册服务(甚至Bar可以不用手动注册,自动解析会自动创建) $container->add(FooBar::class); $foo = $container->get(FooBar::class);
关键区别说明
- 传递
Bar::class字符串给addArgument时,容器会将其视为普通字符串值,不会解析为服务实例。 - 传递服务标识符(如
'bar')或启用自动解析时,容器会查找对应服务并注入实例。
内容的提问来源于stack exchange,提问作者Andreas
相关产品推荐
相关产品推荐

