I would like to thank you all for your answers, but I shall give you my reply in order to clarify.
How objects work in PHP?
First, let’s reinforce some terms:
Object is an instance of a class.
Second, let’s clarify something: in PHP, I can have two instances of stdClass
($a
and $b
), but if I match $c
to $a
, the two will be the same object working in the same instance (which is changed in $c
implies change in $a
).
That is to say:
$a
, $b
and $c
are instances of stdClass
, however $c
and $a
is the same object, since $c
refers to $a
- in php the assigned objects are automatically passed by reference, according to the manual.
Suppose the following scenario:
$a = new stdClass;
$b = new stdClass;
$c = $a;
That:
[$a, $b, $c]
It would be the same thing as that:
[$a, $b, $a]
For $c
become a new instance of stdClass
, independent of the instance held in $a
, we’d have to use the keyword clone
.
Thus:
$c = clone $a
Splobjectstorage - The Solution
So, to return an array of objects with unique instances (instances of the same object, but not repeating these objects), we could do so:
$a = new stdClass;
$a->id = 1;
$b = $a;
$b->id = 2;
$c = new stdClass;
$c->id = 3;
$storage = new SplObjectStorage();
$storage->attach($a);
$storage->attach($b);
$storage->attach($c);
print_r(iterator_to_array($storage));
The result would be:
Array
(
[0] => stdClass Object
(
[id] => 2
)
[1] => stdClass Object
(
[id] => 3
)
)
Note that the id
which was 1, became 2
.
To understand what I say, see what happens in this example:
$a = new stdClass;
$a->id = 1;
$b = $a;
$b->id = 2;
var_dump($a->id, $b->id); // int 2 e int 2
http://3v4l.org/nCG4J
Because it happened?
Because, internally, the SplObjectStorage
, uses the object hash as the index to assign it to a array
.
This is done through a function called spl_object_hash
:
Take this example:
var_dump(spl_object_hash($a));
var_dump(spl_object_hash($b));
var_dump(spl_object_hash($c));
var_dump(spl_object_hash($a) === spl_object_hash($b));
var_dump(spl_object_hash($a) === spl_object_hash($c));
var_dump(spl_object_hash($b) === spl_object_hash($c));
The result is:
string '0000000076e70b6400007fac140b77fd' (length=32)
string '0000000076e70b6400007fac140b77fd' (length=32)
string '0000000076e70b6500007fac140b77fd' (length=32)
boolean true
boolean false
boolean false
This makes it clear that $c
and $a
, are the same.
Then I leave my small contribution. Thank you for the answers!
Why not array_unique?
Because he doesn’t use the same rule of "oneness" as the SplObjectStorage
uses.
Take this example:
$a = new stdClass;
$a->id = 2;
$b = new stdClass;
$b->id = 2;
$case1 = array_unique([$a, $b], SORT_REGULAR);
$storage = new SplObjectStorage();
$storage->attach($a);
$storage->attach($b);
$case2 = iterator_to_array($storage);
var_dump($case1, $case2);
See the results:
#array_unique
array (size=1)
0 =>
object(stdClass)[6]
public 'id' => int 2
#SplObjectStorage com iterator_to_array
array (size=2)
0 =>
object(stdClass)[6]
public 'id' => int 2
1 =>
object(stdClass)[7]
public 'id' => int 2
Example: http://3v4l.org/hQKL5
It seems that the array_unique
took into consideration the fact that id
have the same value in both cases, however, as stated earlier, SplObjectStorage
took into account the internal identification of the object.
If I’m wrong about something, you can fix me :). But that’s what I mean by objects in PHP!
I can already predict answers with
spl_object_hash
andSplObjectStorage
:) :) :) :)– Wallace Maxters