0

I get stuck with a strange PHP behaviour after a cast. Here is the code :

$obj = new stdClass();
$obj->{'0'} = "test";

$array = (array)$obj;
var_dump($array);

This code will output :

array(1) { ["0"]=> string(4) "test" } 

Absolutely normal.

Now I add some code :

foreach ($array as $key => $value) {
   $array[$key] = strtoupper($value);
}
var_dump($array);

This code outputs :

array(2) {
  ["0"]=>
  string(4) "test"
  [0]=>
  string(4) "TEST"
}

Why my $key casted to int ?

If I try a simpler example :

$array = array("0" => "test");
foreach ($array as $key => $value) {
  $array[$key] = strtoupper($value);
}

var_dump($array);

This will output :

array(1) { [0]=> string(4) "TEST" }

Does somebody know why there is a cast of my $key to int ?

Update

I tried to force to cast my key to string :

$array["{$key}"] = $value;

and

$array[(string)$key] = $value;

But they are inserted as int. So my question should be : is there a way to insert keys as string into an array?

I know that I can solve my problem by using a second array and dismiss strings :

$obj = new stdClass();
$obj->{'0'} = "test";
$array = (array)$obj;
$array2 = array();
foreach ($array as $key => $value) {
  $array2[$key] = strtoupper($value);
}

But it would be nice to make it in a more beautiful way, conserving data type (and avoiding duplicating entries while iterating them as previously demonstrated).

Alain Tiemblo
  • 36,099
  • 17
  • 121
  • 153
  • 1
    Note, you can say `$array = array(); foreach ($obj as $key => $value) { $array[$key] = strtoupper($value); }` and skip the ugliness of the `(array)` cast entirely. PHP turns numeric strings into ints to make arrays work more like you'd expect in the face of possibly stringified ints, but objects carry co such expectation. – cHao Sep 13 '12 at 18:30
  • Thanks for this advice, didn't knew a so simpler thing :o! – Alain Tiemblo Sep 13 '12 at 18:37

2 Answers2

1

From the PHP manual:

Strings containing valid integers will be cast to the integer type. E.g. the key "8" will actually be stored under 8. On the other hand "08" will not be cast, as it isn't a valid decimal integer.

Green Black
  • 5,037
  • 1
  • 17
  • 29
0

@cHao found a clean and working solution to convert an object to an array without foreach() matters. My example becomes :

$array = array();
$obj = new stdClass();
$obj->{'0'} = "test";
foreach ($obj as $key => $value) {
   $array[$key] = strtoupper($value);
}

stdClass is iterable.

Thank you!

Alain Tiemblo
  • 36,099
  • 17
  • 121
  • 153