【问题标题】:Compare objects on equality in PHP在 PHP 中比较对象的相等性
【发布时间】:2015-02-06 09:04:11
【问题描述】:

具体说明

首先,在我的例子中,“平等”的定义是——当对象具有相同的结构和该结构的值时,它们是相等的。但是,它们可能不是同一个实例,或者属性可能不是相同的“顺序”(我的意思是,因为它们被分配/定义)。 SO上有类似的问题,例如this - 但它们不涉及我的情况。

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

$result = $objectX == $objectY;

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

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

当前方法

我有像this 这样的代码(太多了,无法直接粘贴到这里,但以防万一,这里是gist) - 所以我在那里执行DFS 并使用这种循环引用来捕捉情况。如您所见,它非常复杂 - 顺便说一下,它很慢。

当前方法的另一个问题是 - 当对象内部有数组时,它们将根据元素顺序进行比较,在某些情况下,这对我来说并不好(理想情况 - 当我能够切换顺序比较),但要在本机上克服它,我可能需要以某种方式对数组进行“排序”——我不知道该怎么做——因为同样,这些数组元素的比较也不安全。

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

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

问题

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

【问题讨论】:

  • get_object_vars($objectX) == get_object_vars($objectY)
  • @DaveRandom 否,因为:1. 循环引用(要点); 2.无序属性比较(也是重点)

标签: php object comparison circular-reference


【解决方案1】:

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

那个方法“export”可以防止你无限循环并返回一个可以用来制作差异的数组。

超过一定深度,没必要再往前走 使用 $maxDepth 您可以指定比较的“准确度”。

【讨论】:

  • 查看code 我发现此方法旨在依赖$maxDepth,如果未设置该方法将失败。 “失败”是指它不会做任何有用的工作,只需打印出类名即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-24
  • 1970-01-01
相关资源
最近更新 更多