致命错误:嵌套级别太深 - 递归依赖关系?

2022-08-30 15:46:27

我有一个复杂的嵌套对象层次结构,所有子对象(在父类中存储了一个对象数组)都包含一个链接到其父对象的属性:相当简单明了,没有真正的问题。如果我对层次结构中的任何对象进行var_dump,我将在转储中获得递归引用,正如我所期望的那样。

FIRSTGEN 
   _children array of objects of type SECONDGEN
      SECONDGEN #1
         _parent object of type FIRSTGEN
         _children array of objects of type THIRDGEN
            THIRDGEN #1
               _parent object of type SECONDGEN
            THIRDGEN #2
               _parent object of type SECONDGEN
      SECONDGEN #2
         _parent object of type FIRSTGEN
         _children array of objects of type THIRDGEN
            THIRDGEN #3
               _parent object of type SECONDGEN

我最近向该层次结构添加了一些新元素,但它们不遵循完全相同的模式。它们存储在顶级父级的对象数组中,但包含一个属性,这些对象不是链接到它们的父级,而是链接到同级。当我现在做一个var_dump时,我得到一个“致命错误:嵌套级别太深 - 递归依赖关系?

FIRSTGEN 
   _children_1 array of objects of type SECONDGEN_1
      SECONDGEN_1 #1
         _parent object of type FIRSTGEN
         _children array of objects of type THIRDGEN
            THIRDGEN #1
               _parent object of type SECONDGEN_1
            THIRDGEN #2
               _parent object of type SECONDGEN_1
      SECONDGEN_1 #2
         _parent object of type FIRSTGEN
         _children array of objects of type THIRDGEN
            THIRDGEN #3
               _parent object of type SECONDGEN_1
   _children_2 array of objects of type SECONDGEN_2
      SECONDGEN_2 #1
         _parent object of type SECONDGEN_1

代码中的其他所有内容都正常工作,除了该var_dump()。我尝试创建一个更简单的示例来演示问题,以便在提出此问题时可以提供示例;但是无法在简短的测试中复制它,只能在我更复杂的代码中复制它。

我知道解决方案是重构关系,以便我的_children_2 SECONDGEN_2对象数组保存在适当的SECONDGEN_1父级中,从而使父级关系“正确”......我已经开始这样做了。但是,我对这个错误很感兴趣,并想知道是否有其他人遇到过它(以及你自己如何处理它)。


答案 1

如果您使用而不是=====

如果需要比较实际对象实例,请始终使用严格比较运算符,因为它仅在对象引用同一类的同一实例时才进行比较。===

简短说明:

如果使用 比较对象,PHP 会将第一个对象的每个属性和值与第二个对象进行比较。这种比较对对象是递归的,对象是被比较对象的属性。$object == $objectToCompareWith

这意味着,如果两个对象共享一个属性,并将一个对象作为其值,PHP 将在这些属性对象之间执行相同的比较。现在,只要这些属性对象是递归的(例如,自引用对象),比较也会递归,直到达到最大嵌套级别。==

正如Josh Stuart和mazatwork的评论中所述,在使用数组函数(如)时,可以通过将其各自的参数设置为来强制进行严格的比较。in_array()array_search()$stricttrue

理查德·洛德:“嵌套层次太深了——递归依赖?

PHP 手册:“比较对象”


答案 2

在自引用代码中看起来像 PHP 限制,并尝试用 、 、 显示它,或者用 搜索它。基本上,如果一个对象被循环引用,这些函数就无法知道在哪里停止递归。print_rvar_dumpvar_exportin_array

根据此错误报告重现此问题的最简单方法是:

$outText = var_export( $GLOBALS, true );
print_r($outText) ;

其他错误报告也提到了它,还有更多的测试用例。我想说的是,如果这只是在触发的,你不应该太担心它。我绝对同意Wrikken关于xdebug的建议,如果这是出于调试目的。var_dump


推荐