问题
I am looking for a way to generate some kind of hash for PHP object (generic solution, working with all classed, built-in and custom, if possible).
SplObjectStorage::getHash is not what I'm looking for, as it will generate different hash for every instance of given class. To picture the problem, let's consider simple class:
class A() {
public $field; //public only for simplicity
}
and 2 instances of that class:
$a = new A(); $a->field = 'b';
$b = new A(); $b->field = 'b';
Every built-in function I've tried will return different hashes for these objects, while I'd like to have some function f($x)
with property f($a) == f($b) => $a == $b
.
I am aware I could write a function traversing all object's properties recursively until I find a property that can be casted to string, concatenate this strings in fancy way and hash, but the performance of such solution would be awful.
Is there an efficient way to do this?
回答1:
Assuming I understand you correctly, you could serialize the objects then md5 the serialized object. Since the serialization creates the same string if all properties are the same, you should get the same hash every time. Unless your object has some kind of timestamp property. Example:
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";
output:
0a0a68371e44a55cfdeabb04e61b70f7
0a0a68371e44a55cfdeabb04e61b70f7
Yours are coming out differently because the object in php memory is stored with a numbered id of each instantiation:
object(A)#1 (1) {...
object(A)#2 (1) {...
回答2:
You appear to be talking about a Value Object. It is a pattern where each such object isn't compared according to the object identity, but about the contents - fully, or partially, of the properties that make up the object.
I'm using a number of them in a project:
public function equals(EmailAddress $address)
{
return strtolower($this->address) === strtolower((string) $address);
}
A more complex object could simply add more items into the comparison function.
return ($this->one === $address->getOne() &&
$this->two === $address->getTwo());
As such conditionals (all joined with '&&') will short-cut to false as soon as any item does not match.
来源:https://stackoverflow.com/questions/31659187/php-hash-objects-in-a-way-distint-object-with-same-fields-values-have-same-has