php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67640 Object to array cast results in duck typing
Submitted: 2014-07-17 10:12 UTC Modified: 2015-05-19 11:47 UTC
Votes:3
Avg. Score:3.7 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:0 (0.0%)
From: php at kingsquare dot nl Assigned: cmb (profile)
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.5.14 OS: n/a
Private report: No CVE-ID: None
 [2014-07-17 10:12 UTC] php at kingsquare dot nl
Description:
------------
Creating objects from (i.e.) a JSON string and casting that to an array results in something that looks like an array, acts like an array, but in reality is still an object? (or atleast suffers from not supporting numeric properties on objects)

I know objects can't have numeric properties but dumping the object _and_ array works as intended... then accessing the array by index 0 it fails? (but accessing the object property like $obj->{"0"} works, thus i'd expect $array[0] / $array['0'] to work as well ?

(see reports: 45346 / 61655 perhaps?)

I know about the lookup / juggling mismatch (the index is actually a string "0" but access via index is juggled into an int and thus cant be found...) Although i understand the problem it has some issues:
first and foremost: i expected it to work ;) (since creating an $foo = array("1"=>"test") will work with $foo[1], so from a user perspective there should be no difference

- this specific use case seems undocumented ?
- If var_dump-ing the resulting array i should be able to either use array_key_exists or by derefencing to access the key ... If not: var_dump should not show it / mention it.. ;)



Test script:
---------------
$json = '{ "0" : "test1" }';
// just decode that into an object
$obj = json_decode($json);
// recast it into an array
$array = (array) $obj;
// just dump to see the results
var_dump($obj, $array, $array['0'], $array[0]);

Actual result:
--------------
Notices on the undefined index: 0

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-07-18 11:04 UTC] mightyuhu@php.net
In this case i'd expect $array to look like 

array(1) { [0]=> string(5) "test1" }

instead of

array(1) { ["0"]=> string(5) "test1" }



test code:

<?php
$json = '{ "0" : "test1" }';
// just decode that into an object
$obj = json_decode($json);
// recast it into an array

$array = get_object_vars($obj);
// just dump to see the results
var_dump($obj,$array, $array[0], $array['0']); 
//object(stdClass)#1 (1) { ["0"]=> string(5) "test1" } array(1) { [0]=> string(5) "test1" } string(5) "test1" string(5) "test1"


$array2 = (array) $obj;
var_dump($obj,$array2, $array2[0], $array2['0']);
//E_NOTICE : type 8 -- Undefined offset: 0 -- at line 10
E_NOTICE : type 8 -- Undefined index: 0 -- at line 10

$array3 = json_decode($json,true);
var_dump($array3, $array3[0], $array3['0']);
//object(stdClass)#1 (1) { ["0"]=> string(5) "test1" } array(1) { ["0"]=> string(5) "test1" } NULL NULL array(1) { [0]=> string(5) "test1" } string(5) "test1" string(5) "test1"

?>
 [2014-07-18 11:29 UTC] php at kingsquare dot nl
I'd expect it to be a string due to the json data itself:
$json = '{ "0" => "test" }';

and not:
$json = '{ 0 => "test" }';

In either case: fetching the array using the index would juggle it into int anyway (thus $array[0] == $array["0"] == "test")
 [2014-07-19 17:08 UTC] mightyuhu@php.net
The manual states:

A key may be either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. "8" will be interpreted as 8, while "08" will be interpreted as "08").

http://php.net/manual/en/language.types.array.php 

So according to this i expect 
$json = '{ 0 => "test" }';
 [2014-07-23 09:14 UTC] php at kingsquare dot nl
True, and the point isn't that the key should be a string or an integer but that it isn't found at all :)

$json = '{ "0" : "test1" }';
$obj = json_decode($json);
// recast it into an array
$array = (array) $obj;
$array[0] == "test1"
// throws error that the index can't be found but is shown in a var_dump
 [2015-05-19 11:47 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2015-05-19 11:47 UTC] cmb@php.net
This is not a bug in PHP. The behavior of casting objects to
arrays is well documented[1]:

| The keys are the member variable names, with a few notable
| exceptions: integer properties are unaccessible; [...]

Instead of

  (array) json_decode($json)
  
simply use

  json_decode($json, true)
  
to get the desired array in the first place.

[1] <http://php.net/manual/en/language.types.array.php#language.types.array.casting>
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jun 28 18:01:34 2025 UTC