Thank you all for the answers, but in this case, I will give my answer, to give some clarification.
How do 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 equal $c
$a
, the two will be the same object working in the same instance (what is changed in $c
implies change in $a
).
That is:
$a
, $b
and $c
are instances of stdClass
, however $c
and $a
is the same object, since $c
refers to $a
- in php 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 as this:
[$a, $b, $a]
For $c
to become a new instance of stdClass
, regardless of instance stored in $a
, we would have to use the keyword clone
.
So:
$c = clone $a
SplObjectStorage - The Solution
Then, to return an array of objects with unique instances (instances of the same object, but not repeating these objects), we could do this:
$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% w_that% was 1, became% w_th of%.
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
link
Why did this happen?
Because, internally, id
, uses the hash of the object as the index to assign it to a 2
.
This is done through a function called SplObjectStorage
:
See 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 array
and spl_object_hash
, are the same.
I leave my little contribution there. Thanks for the answers!
Why not array_unique?
Because it does not use the same "uniqueness" rule that $c
uses.
See 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);
View 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: link
It seems that $a
took into account the fact that SplObjectStorage
has the same value in both cases, however, as previously stated, array_unique
took into account the internal identification of the object.
If I'm wrong about something, you can correct me :). But that's what I mean by objects in PHP!