PHP hash objects in distint object way with same field values ​​have the same hash

I'm looking for a way to generate some sort of hash for a PHP object (general solution, work with all classified, inline and custom ones if possible).

SplObjectStorage :: getHash is not what I am looking for as it will generate different hashes for each instance of a given class. To introduce the problem, consider a simple class:

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

      

and 2 instances of this 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 would like to have some function f($x)

with a property f($a) == f($b) => $a == $b

.

I know that I could write a function that loops through all properties of an object recursively until I find a property that can be distinguished from a string, concatenate those strings in style and a hash, but the performance of such a solution would be terrible.

Is there an efficient way to do this?

+3


source to share


2 answers


Assuming I understand you correctly, you can serialize objects and then md5 is the serialized object. Since serialization produces the same string, if all properties are the same, you should get the same hash every time. If your object doesn't have any 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 come out differently because the object in php memory is stored with a numbered id of each instance:

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

      

+2


source


You seem to be talking about a Value object. This is a pattern where each such object is not compared according to the object identifier, but about the content - in whole or in part of the properties that make up the object.

I am using several of these in a project:

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

      



A more complex object can simply add more elements to the comparison function.

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

      

Because such conventions (they are all concatenated with '& &') will be truncated to false as soon as any element fails.

0


source







All Articles