容器是怎么避免"循环依赖把栈撑爆"的

顺带把反射和闭包的重复开销也省掉

装配 A 的时候发现它要 B,装配 B 又要 A —— 这就是循环依赖。麻烦的不只是"会不会成环",还有"多快能发现":如果每次压栈都拿 in_array() 把整条链扫一遍,栈一深,光查环就吃掉不少时间。

这里的做法是压栈的同时往一张 hash 表写一份,于是"在不在栈里"变成一次 isset():

$this->buildStack[] = $abstract;          // 依赖链,用来报错时把整条链打出来
$this->buildMap[$abstract] = true;       // 同一份数据的 hash 视图,只用来查环
if (isset($this->buildMap[$next])) { /* 立刻发现环 */ }

顺带解决的是另外两处重复开销:同一个类的 ReflectionClass 与构造参数只解析一次后存起来;注册的闭包第一次解析完就被整理成一个"预编译工厂",把参数名提前记下来,之后不再碰 ReflectionFunction。

内容信息

作者
aucms 团队
来源
技术博客
发布日期
2026-10-22
难度
hard
推荐
1
模型
文章