Last modified: 2012-04-12 14:00:08 UTC
The wfObjectToArray global function, when called with $recursive = true, does not recurse through properties of the object that are arrays. As a result, if objects are nested inside these arrays, they will not be converted. An example of a object to array conversion function that *does* handle nested arrays is at http://www.phpro.org/examples/Convert-Object-To-Array-With-PHP.html (at the bottom). I encountered this problem while trying to use the ForeignAPIRepo feature on my wiki with a PHP installation that does not have the builtin JSON functions. It uses FormatJson::decode(), which falls back on Services_JSON to decode the data. FormatJson then converts the decoded object to an array using wfObjectToArray, which is where this failure happens. The end result is this error message: Fatal error: Cannot use object of type stdClass as array in /home/mscs/common/devel/www/html/projects/beowulf/wiki.real/includes/filerepo/ForeignAPIFile.php on line 102 Interestingly, Services_JSON has its own way of returning arrays instead of objects--the flag SERVICES_JSON_LOOSE_TYPE. If FormatJson used this instead, it could bypass wfObjectToArray completely. Perhaps there are two bugs here. I will try to submit patches tomorrow.
Oops. That line number in the error message should be 101--I added a line in the process of debugging.
Created attachment 7436 [details] wfObjectToArray Patch Here is a patch for wfObjectToArray(). It isn't the prettiest, but it works. I've tested it on my wiki.
Created attachment 7437 [details] FormatJson "loose typing" patch This separate patch changes FormatJson to use Service_JSON's built-in method for specifying "loose typing", where objects are decoded as arrays. It avoids using wfObjectToArray in the first place. It works together with the other patch or separately.
wfObjectToArray fix patch committed on trunk with whitespace cleanup in r82090. FormatJson tweak to use Services_JSON's native associate array output applied on trunk in r82091. Both good catches and good fixes -- thanks for the patches Tim!
I think this is still broken: > $s = FormatJson::encode(array( 'a' => array( array( 'b' => 'c' ) ) ) ); > print $s; {"a":[{"b":"c"}]} > var_dump(FormatJson::decode($s)); object(stdClass)#11 (1) { ["a"]=> array(1) { [0]=> object(stdClass)#12 (1) { ["b"]=> string(1) "c" } } } > print SpecialVersion::getSvnRevision( $IP ); 82934
Ah, the problem is that wfObjectToArray is not called at all for json_decode.
Reclosing, was based on a misunderstanding from my side.