Page MenuHomePhabricator

wfObjectToArray does not recurse into arrays
Closed, ResolvedPublic

Description

Author: supreme_geek_overlord

Description:
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.


Version: 1.16.x
Severity: normal

Details

Reference
bz23817

Event Timeline

bzimport raised the priority of this task from to Medium.Nov 21 2014, 11:08 PM
bzimport set Reference to bz23817.

supreme_geek_overlord wrote:

Oops. That line number in the error message should be 101--I added a line in the process of debugging.

supreme_geek_overlord wrote:

wfObjectToArray Patch

Here is a patch for wfObjectToArray(). It isn't the prettiest, but it works. I've tested it on my wiki.

Attached:

supreme_geek_overlord wrote:

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.

Attached:

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!

Bryan.TongMinh wrote:

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

Bryan.TongMinh wrote:

Ah, the problem is that wfObjectToArray is not called at all for json_decode.

Bryan.TongMinh wrote:

Reclosing, was based on a misunderstanding from my side.