PHP bug with converting object to arrays

2019-02-24 23:55发布

问题:

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:

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;



回答2:

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.



回答3:

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

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

unserialize(serialize($arr));