views:

273

answers:

3

I had this question earlier and it was concluded it was a bug in 5.2.5. Well, it's still broken in 5.2.6, at least for me:

Please let me know if it is broken or works for you:

$obj = new stdClass();
$obj->{"foo"} = "bar";
$obj->{"0"} = "zero";
$arr = (array)$obj;

//foo -- bar
//0 --    {error: undefined index}
foreach ($arr as $key=>$value){
    echo "$key -- " . $arr[$key] . "\n";
}

Any ways to "fix" the array after it has been cast from a stdClass?

+1  A: 

Definitely seems like a bug to me (PHP 5.2.6).

You can fix the array like this:

$arr = array_combine(array_keys($arr), array_values($arr));

It's been reported in this bug report but marked as bogus... the documentation says:

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

Greg
IMO this is definitely a bug. Just because a string happens to look like an integer it is not a valid index? C'mon... this is is causing me a great deal of trouble.
A: 

Thanks RoBorg.. I just discovered that as well :)

Here's another solution, not sure if it's faster or not:

unserialize(serialize($arr));
I've found (un)serialize to be fairly slow in the past but I've no idea what the performance of array_combine is
Greg
I've just done a test trying both the serialization and the array_combine on arrays with 100 indexes (keys: random string between 5 and 10, values: random string between 1 and 500). The results are less than 1% apart, with a array_combine being consistantly faster.
+1  A: 

A bit of experimentation shows phps own functions don't persist this fubarity.

function noopa( $a ){ return $a; }
$arr = array_map('noopa', $arr ); 
$arr[0]; # no error!

This in effect, just creates a copy of the array, and the fix occurs during the copy.

Ultimately, its a design failure across the board, try using array_merge in the way you think it works on an array with mixed numeric and string keys?

All numbered elements get copied and some get re-numbered, even if some merely happen to be string-encapsulated-numbers, and as a result, there are dozens of homebrew implementations of array_merge just to solve this problem.

Back when php tried to make a clone of perl and failed, they didn't grasp the concept of arrays and hashes being distinct concepts, an instead globbed them together into one universal umbrella. Good going!.

For their next trick, they manage to break namespace delimiters because of some technical problem that no other language has for some reason encountered.

Kent Fredric
The namespace thing is ridiculous. But as per the arrays thing, I like it. They went wrong in casting strings to integers for keys. $arr["0"] should be distinct from $arr[0] ... they should be both allowed in the same array.