比较PHP中的相等对象

时间:2015-02-06 09:04:11

标签: php object comparison circular-reference

具体细节信息

首先,"平等的定义"在我的情况下 - 当对象具有相同的结构和该结构的值时,它们是相等的。但是,它们可能不是同一个实例,或者属性可能不相同" order" (我的意思是,因为他们被分配/定义)。这里有类似的问题,如this - 但它们并没有涵盖我的案例。

由于我的代码测试目的,我需要比较PHP中的实体 - 这些实体可能是任何东西。特别是,它们可能是物体。但是,Objects comparison不安全"。想象一下,你正在比较:

$result = $objectX == $objectY;

如果对象具有循环引用,则可能导致致命错误。我准备了here的简单示例。正如我们所看到的,PHP试图遵循嵌套级别并在无限循环中失败 - 因为自然对象在内容上是相同的,但具有循环引用。

重要的细节是对象可能包含不可序列化的东西(如闭包),这使得无法依赖" seralize / unserialize"方法(即使忘记无序比较)

当前方法

我有像this这样的代码(在这里直接粘贴太多了,但以防万一,这里是gist) - 所以我在那里执行DFS并抓住情况有这样的循环参考。正如你所看到的,它非常复杂 - 顺便说一句,它很慢。

当前方法的另一个问题是 - 当对象内部有数组时,它们将在元素顺序方面进行比较,在某些情况下,这对我来说并不合适(理想情况 - 当我成为时)能够切换顺序比较),但为了克服它原生,我可能需要"排序"数组以某种方式 - 我不知道如何做到这一点 - 再次,这些数组元素的比较将是不安全的。

而且,循环数组引用也会导致失败:

$array = ['foo', $object, &$array];

问题

解决问题的其他(更好)方法可能是什么?序列化对象可能就是这种情况,但由于非有序的属性集,它将失败。

1 个答案:

答案 0 :(得分:1)

你知道Doctrine \ Common \ Util \ Debug :: export($ class,$ maxDepth)吗?

该方法“导出”会阻止您进行无限循环并返回一个可用于制作差异的数组。

超过一定深度,没有必要走得更远 使用$ maxDepth,您可以指定比较的“准确性”。