我正在寻找一种为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
。
我知道我可以编写一个递归遍历所有对象属性的函数,直到我找到一个可以转换为字符串的属性,以花哨的方式连接这些字符串和哈希,但这种解决方案的性能会很差。
有一种有效的方法吗?
答案 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());
因为这些条件(所有加入'&&')会在任何项目不匹配时立即缩短为假。