What is the best way to prevent duplicate key during type casting ?
Example :
//Credits @bwoebi
$obj = (object)array(1,2,3);
$obj->{1} = "Duplicate key 1";
$obj->{2} = "Duplicate key 2";
$obj->{3} = "Duplicate key 3";
$array = (array)$obj ;
print_r($array);
Output
Array
(
[0] => 1
[1] => 2
[2] => 3
[1] => Duplicate key 1
[2] => Duplicate key 2
[3] => Duplicate key 3
)
Now i know some smart people would say its because one key
is string
and the other int
use var_dump
var_dump($array);
Output
array (size=6)
0 => int 1
1 => int 2
2 => int 3
'1' => string 'Duplicate key 1' (length=15)
'2' => string 'Duplicate key 2' (length=15)
'3' => string 'Duplicate key 3' (length=15)
But the main issue is there is no way to even get the key
echo $array['1'] ,PHP_EOL; //Expected Duplicate key 1
echo $array[1] ,PHP_EOL;
Output
2
2
Is there any workaround to this issue without having to loop ? Obviously i would never make this mistake unless @PeeHaa埽 gives be beer again, but I think any answer should help educated PHP
developers.
Note.
- This can easly be resolved with array_values
, sort
or any php function that changes key position
Example
sort($array);
print_r($array);
Output
Array
(
[0] => Duplicate key 1
[1] => Duplicate key 2
[2] => Duplicate key 3
[3] => 1
[4] => 2
[5] => 3
)
You can use array_values function to reset array keys.
Try this:
$obj = (object)array(1,2,3);
$obj->{1} = "Duplicate key 1";
$obj->{2} = "Duplicate key 2";
$obj->{3} = "Duplicate key 3";
$array = (array)$obj ;
$array = array_values($array);
print_r($array);
Produces this:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => Duplicate key 1
[4] => Duplicate key 2
[5] => Duplicate key 3
)
Or you can even use array_values before casting like this:
$array = array_values((array)$obj);
Hope this helps!
Maybe not the best solution, but using a custom function to cast arrays to objects would solve part of the problem.
// function that convers an array to an object, and prefixes the numeric values with a string
function toObj(Array $arr, $prefix = '_', $convertAll = false ) {
foreach ($arr as $key => $value) {
if (is_numeric($key) || $convertAll) {
unset($arr[$key]);
$arr[$prefix . $key] = $value;
}
}
return (object)$arr;
}
$obj = toObj(array(1, 2, 3));
$obj->{'_0'} = "Duplicate key 0"; // either this way
$obj->_1 = "Duplicate key 1"; // or this way
$obj->{'_2'} = "Duplicate key 2";
$array = (array)$obj;
print_r($array);
The result is:
Array
(
[_0] => Duplicate key 0
[_1] => Duplicate key 1
[_2] => Duplicate key 2
)
Although this is similar to the array_values
solution, it has the benefit of still keeping the keys, at least to a certain degree.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With