Created
August 10, 2013 15:27
-
-
Save elyobo/6200838 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use PHPUnit_Framework_TestCase as BaseTestCase; | |
class TestFixer extends BaseTestCase | |
{ | |
public function fix(&$target, $source, $keep = false) { | |
if (!$source) { | |
return; | |
} | |
$keys = array(); | |
$source = preg_replace_callback( | |
'/ | |
# Match at start of string or & | |
(?:^|(?<=&)) | |
# Exclude cases where the period is in brackets, e.g. foo[bar.blarg] | |
[^=&\[]* | |
# Affected cases: periods and spaces | |
(?:\.|%20) | |
# Keep matching until assignment, next variable, end of string or | |
# start of an array | |
[^=&\[]* | |
/x', | |
function ($key) use (&$keys) { | |
$keys[] = $key = base64_encode(urldecode($key[0])); | |
return urlencode($key); | |
}, | |
$source | |
); | |
if (!$keep) { | |
$target = array(); | |
} | |
parse_str($source, $data); | |
foreach ($data as $key => $val) { | |
// Only unprocess encoded keys | |
if (!in_array($key, $keys)) { | |
$target[$key] = $val; | |
continue; | |
} | |
$key = base64_decode($key); | |
$target[$key] = $val; | |
if ($keep) { | |
// Keep a copy in the underscore key version | |
$key = preg_replace('/(\.| )/', '_', $key); | |
$target[$key] = $val; | |
} | |
} | |
} | |
public function dataForTestFix() | |
{ | |
return array( | |
// Simple cases | |
['foo=bar', ['foo' => 'bar']], | |
['foo=foo.bar', ['foo' => 'foo.bar']], | |
['foo=foo.bar[]', ['foo' => 'foo.bar[]']], | |
['foo[]=bar', ['foo' => ['bar']]], | |
['foo.bar', ['foo.bar' => '']], | |
['foo.bar[]', ['foo.bar' => ['']]], | |
['foo%20bar', ['foo bar' => '']], | |
['foo%20bar[]', ['foo bar' => ['']]], | |
['foo[foo.bar]=bar', ['foo' => ['foo.bar' => 'bar']]], | |
['foo[foo%20bar]=bar', ['foo' => ['foo bar' => 'bar']]], | |
// Simple cases with keeping | |
['foo=bar', ['foo' => 'bar'], true], | |
['foo=foo.bar', ['foo' => 'foo.bar'], true], | |
['foo=foo.bar[]', ['foo' => 'foo.bar[]'], true], | |
['foo[]=bar', ['foo' => ['bar']], true], | |
['foo.bar', ['foo_bar' => '', 'foo.bar' => ''], true], | |
['foo.bar[]', ['foo_bar' => [''], 'foo.bar' => ['']], true], | |
['foo%20bar', ['foo_bar' => '', 'foo bar' => ''], true], | |
['foo%20bar[]', ['foo_bar' => [''], 'foo bar' => ['']], true], | |
['foo[foo.bar]=bar', ['foo' => ['foo.bar' => 'bar']], true], | |
['foo[foo%20bar]=bar', ['foo' => ['foo bar' => 'bar']], true], | |
// Duplicates if cast to "_" | |
['foo.bar=blarg1&foo_bar=blarg2&foo%20bar=blarg3', ['foo.bar' => 'blarg1', 'foo_bar' => 'blarg2', 'foo bar' => 'blarg3']], | |
['foo.bar=blarg1&foo_bar=blarg2&foo%20bar=blarg3', ['foo_bar' => 'blarg3', 'foo.bar' => 'blarg1', 'foo bar' => 'blarg3'], true], | |
array( | |
'foo%20bar=blarg&foo[bar][blarg.bar]=bar&foo.bar=blarg&foobar.blarg[]=bar&blarg.foo&blargfoo.bar[asdf]=w00t&normal=normal', | |
array( | |
'foo bar' => 'blarg', | |
'foo' => array( | |
'bar' => array( | |
'blarg.bar' => 'bar', | |
), | |
), | |
'foo.bar' => 'blarg', | |
'foobar.blarg' => array('bar'), | |
'blarg.foo' => null, | |
'blargfoo.bar' => array( | |
'asdf' => 'w00t', | |
), | |
'normal' => 'normal', | |
) | |
), | |
); | |
} | |
/** | |
* @dataProvider dataForTestFix | |
*/ | |
public function testFixWorks($string, $target, $keep = false) | |
{ | |
parse_str($string, $source); | |
$this->fix($source, $string, $keep); | |
$this->assertEquals($source, $target); | |
} | |
} |
Thanks for sharing, implemented it in a project of mine ;)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
http://stackoverflow.com/questions/68651/get-php-to-stop-replacing-characters-in-get-or-post-arrays