williams_wang williams_wang - 3 months ago 13
PHP Question

use uniqid id where general by spl_object_hash be array's key

today, when i use spl_object_hash() generate unique id be array's key, but the result doesn't like what i think...

class a
{

public $i;

public function __construct($i)
{
$this->i = $i;
}

}

$array = [];

for ($i = 0; $i < 3; $i++)
{

$a = new a(1);

$array[spl_object_hash($a)] = $i;

}

var_dump($array);


the output is:

array(2) {

'0000000053bd5300000000005432750f' =>
int(2)

'0000000053bd5303000000005432750f' =>
int(1)
}


Code:

class a
{
public $i;

public function __construct($i)
{
$this->i = $i;
}
}
$array = [];
for ($i = 0; $i < 3; $i++) {
$a = new a(1);
$array[spl_object_hash($a)] = $a;

}
var_dump($array);


the output is:

array(3) {

'000000005397fe130000000045a81147' =>class a#1 (1) {
public $i =>
int(1)
}

'000000005397fe100000000045a81147' =>class a#2 (1) {
public $i =>
int(1)
}

'000000005397fe110000000045a81147' =>class a#3 (1) {
public $i =>
int(1)
}

}


the display confused me; why output like this ?

Answer

From the first comment in the docs for spl_object_hash():

Note that the contents (properties) of the object are NOT hashed by the function, merely its internal handle and handler table pointer. This is sufficient to guarantee that any two objects simultaneously co-residing in memory will have different hashes. Uniqueness is not guaranteed between objects that did not reside in memory simultaneously, for example:

var_dump(spl_object_hash(new stdClass()), spl_object_hash(new stdClass()));

Running this alone will usually generate the same hashes, since PHP reuses the internal handle for the first stdClass after it has been dereferenced and destroyed when it creates the second stdClass.

Basically, every time you overwrite $a with a new object the reference to the first object is destroyed and the handle is reused for the new object. As a result spl_object_hash() returns the same hash.

To overcome this, assign each object to a new variable:

class a
{
    public $i;

    public function __construct($i)
    {
        $this->i = $i;
    }
}
$array = [];

$a = new a(1);
$array[spl_object_hash($a)] = $a;

$b = new a(1);
$array[spl_object_hash($b)] = $b;

$c = new a(1);
$array[spl_object_hash($c)] = $c;

var_dump($array);

Demo