PHP - 具有相同字段值的distint对象的哈希对象具有相同的哈希值

时间:2015-07-27 17:09:24

标签: php performance hash

我正在寻找一种为PHP对象生成某种哈希的方法(通用解决方案,如果可能的话,使用所有分类,内置和自定义)。

SplObjectStorage :: getHash不是我想要的,因为它会为给定类的每个实例生成不同的哈希。为了描述问题,让我们考虑简单的类:

class A() {
public $field; //public only for simplicity
}

和该类的2个实例:

$a = new A(); $a->field = 'b';
$b = new A(); $b->field = 'b';

我尝试过的每个内置函数都会为这些对象返回不同的哈希值,而我希望有一些带有function f($x)属性的f($a) == f($b) => $a == $b

我知道我可以编写一个递归遍历所有对象属性的函数,直到我找到一个可以转换为字符串的属性,以花哨的方式连接这些字符串和哈希,但这种解决方案的性能会很差。

有一种有效的方法吗?

2 个答案:

答案 0 :(得分:2)

假设我理解正确,您可以序列化对象,然后md5序列化对象。由于序列化在所有属性相同的情况下创建相同的字符串,因此每次都应该获得相同的哈希值。除非您的对象具有某种时间戳属性。例如:

class A {
    public $field;
}
$a = new A;
$b = new A;
$a->field = 'test';
$b->field = 'test';
echo md5(serialize($a)) . "\n";
echo md5(serialize($b)) . "\n";

输出:

0a0a68371e44a55cfdeabb04e61b70f7
0a0a68371e44a55cfdeabb04e61b70f7

你的出现方式不同,因为php内存中的对象存储了每个实例化的编号id:

object(A)#1 (1) {...
object(A)#2 (1) {...

答案 1 :(得分:0)

您似乎在谈论价值对象。这是一种模式,其中每个这样的对象不是根据对象标识进行比较,而是关于内容 - 完全或部分地构成对象的属性。

我在项目中使用了其中的一些:

public function equals(EmailAddress $address)
{
    return strtolower($this->address) === strtolower((string) $address);
}

更复杂的对象可以简单地将更多项添加到比较函数中。

return ($this->one === $address->getOne() && 
    $this->two === $address->getTwo());

因为这些条件(所有加入'&&')会在任何项目不匹配时立即缩短为假。