r90661 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r90660‎ | r90661 | r90662 >
Date:15:25, 23 June 2011
Author:mgrabovsky
Status:ok
Tags:
Comment:
wfArrayToCGI() and wfCgiToArray() now handle nested and associative arrays almost correctly

The only problem is that all the indexes have to be set, thus "key[]=value" won't get parsed correctly and array( 'key' => array( 'value' ) ) will transform to "key[0]=value".

Related bug 28928 and bug 22989.
Modified paths:
  • /trunk/phase3/RELEASE-NOTES-1.19 (modified) (history)
  • /trunk/phase3/includes/GlobalFunctions.php (modified) (history)
  • /trunk/phase3/tests/phpunit/includes/GlobalTest.php (modified) (history)

Diff [purge]

Index: trunk/phase3/RELEASE-NOTES-1.19
@@ -115,6 +115,8 @@
116116 * (bug 29507) Change 'image link' to 'file link' in Special:Whatlinkshere
117117 * If the db is really screwed up, and doesn't have a recentchanges table,
118118 make the updater throw an exception instead of a fatal.
 119+* wfArrayToCGI() and wfCgiToArray() now handle nested and associative arrays
 120+ correctly
119121
120122 === API changes in 1.19 ===
121123 * BREAKING CHANGE: action=watch now requires POST and token.
Index: trunk/phase3/tests/phpunit/includes/GlobalTest.php
@@ -102,8 +102,20 @@
103103 wfArrayToCGI(
104104 array( 'baz' => 'AT&T', 'ignore' => '' ),
105105 array( 'foo' => 'bar', 'baz' => 'overridden value' ) ) );
 106+ $this->assertEquals(
 107+ "path%5B0%5D=wiki&path%5B1%5D=test&cfg%5Bservers%5D%5Bhttp%5D=localhost",
 108+ wfArrayToCGI( array(
 109+ 'path' => array( 'wiki', 'test' ),
 110+ 'cfg' => array( 'servers' => array( 'http' => 'localhost' ) ) ) ) );
106111 }
107112
 113+ function testCgiToArray() {
 114+ $this->assertEquals(
 115+ array( 'path' => array( 'wiki', 'test' ),
 116+ 'cfg' => array( 'servers' => array( 'http' => 'localhost' ) ) ),
 117+ wfCgiToArray( 'path%5B0%5D=wiki&path%5B1%5D=test&cfg%5Bservers%5D%5Bhttp%5D=localhost' ) );
 118+ }
 119+
108120 function testMimeTypeMatch() {
109121 $this->assertEquals(
110122 'text/html',
Index: trunk/phase3/includes/GlobalFunctions.php
@@ -318,9 +318,10 @@
319319 *
320320 * @param $array1 Array( String|Array )
321321 * @param $array2 Array( String|Array )
 322+ * @param $prefix String
322323 * @return String
323324 */
324 -function wfArrayToCGI( $array1, $array2 = null ) {
 325+function wfArrayToCGI( $array1, $array2 = null, $prefix = '' ) {
325326 if ( !is_null( $array2 ) ) {
326327 $array1 = $array1 + $array2;
327328 }
@@ -331,20 +332,25 @@
332333 if ( $cgi != '' ) {
333334 $cgi .= '&';
334335 }
 336+ if ( $prefix !== '' ) {
 337+ $key = $prefix . "[$key]";
 338+ }
335339 if ( is_array( $value ) ) {
336340 $firstTime = true;
337 - foreach ( $value as $v ) {
338 - $cgi .= ( $firstTime ? '' : '&') .
339 - urlencode( $key . '[]' ) . '=' .
340 - urlencode( $v );
 341+ foreach ( $value as $k => $v ) {
 342+ $cgi .= $firstTime ? '' : '&';
 343+ if ( is_array( $v ) ) {
 344+ $cgi .= wfArrayToCGI( $v, null, $key . "[$k]" );
 345+ } else {
 346+ $cgi .= urlencode( $key . "[$k]" ) . '=' . urlencode( $v );
 347+ }
341348 $firstTime = false;
342349 }
343350 } else {
344351 if ( is_object( $value ) ) {
345352 $value = $value->__toString();
346353 }
347 - $cgi .= urlencode( $key ) . '=' .
348 - urlencode( $value );
 354+ $cgi .= urlencode( $key ) . '=' . urlencode( $value );
349355 }
350356 }
351357 }
@@ -362,19 +368,34 @@
363369 * @return array Array version of input
364370 */
365371 function wfCgiToArray( $query ) {
366 - if( isset( $query[0] ) && $query[0] == '?' ) {
 372+ if ( isset( $query[0] ) && $query[0] == '?' ) {
367373 $query = substr( $query, 1 );
368374 }
369375 $bits = explode( '&', $query );
370376 $ret = array();
371 - foreach( $bits as $bit ) {
372 - if( $bit === '' ) {
 377+ foreach ( $bits as $bit ) {
 378+ if ( $bit === '' ) {
373379 continue;
374380 }
375381 list( $key, $value ) = explode( '=', $bit );
376382 $key = urldecode( $key );
377383 $value = urldecode( $value );
378 - $ret[$key] = $value;
 384+ if ( strpos( $key, '[' ) !== false ) {
 385+ $keys = array_reverse( explode( '[', $key ) );
 386+ $key = array_pop( $keys );
 387+ $temp = $value;
 388+ foreach ( $keys as $k ) {
 389+ $k = substr( $k, 0, -1 );
 390+ $temp = array( $k => $temp );
 391+ }
 392+ if ( isset( $ret[$key] ) ) {
 393+ $ret[$key] = array_merge( $ret[$key], $temp );
 394+ } else {
 395+ $ret[$key] = $temp;
 396+ }
 397+ } else {
 398+ $ret[$key] = $value;
 399+ }
379400 }
380401 return $ret;
381402 }

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r64351circumventing bug 22989, this is better style anyway. Thanks to Andi H. for h...churchofemacs17:26, 29 March 2010

Status & tagging log