0

I'm trying to create a form which allows the user to define own custom query key and while I was testing the validation function for the form, I've noticed that %20 in a url query key is converted to a underscore in the $_GET array.

$key = 'a b';
$key = rawurlencode($key);
$value = 'value';

print_r($_GET); // output: Array ( [a_b] => value )

echo '<p>key:' . $key . '</p>';
echo '<p>value:' . $value . '</p>';
echo '<p><a href="' . $_SERVER["REQUEST_URI"] . '?' . $key . '=' . $value . '">test</a></p>';

Are there other characters converted irregularly? I'm not sure "irregular" is the right word here since there might be a rule for this behavior but I didn't expect this would happen.

Teno
  • 2,582
  • 4
  • 35
  • 57
  • See also http://stackoverflow.com/questions/68651/can-i-get-php-to-stop-replacing-characters-in-get-or-post-arrays . This relates to the historic behavior of PHP in making this value `$a_b` instead of `$_GET['a_b']`. – Random832 Oct 05 '12 at 04:11
  • Oh, so they should be these four characters. `chr(32) ( ) (space) chr(46) (.) (dot) chr(91) ([) (open square bracket) chr(128) - chr(159) (various)` Thanks for the link. Could you put it in the answer? – Teno Oct 05 '12 at 04:15

2 Answers2

2

PHP replaces certain characters with an underscore because they are illegal in variable names. Even though they are legal in array keys, earlier versions of PHP would put form variables directly in variables (i.e. $a_b; see Register Globals), so this conversion was put in. This is done with space, dot, open square bracket, and control characters between 128 and 159.

This is only done with the names themselves, not to, for example, any array key parameters (i.e. http://example.com/foo.php?a[b.%20c]=1) since any character is legal in an array key. (Note that the array parameter feature itself means that open square bracket will not be replaced with _ as implied by the above in certain situations - the example will give $_GET['a']['b. c'] == 1.)

Source: http://ca.php.net/variables.external

Related question: Get PHP to stop replacing '.' characters in $_GET or $_POST arrays?

Community
  • 1
  • 1
Random832
  • 37,415
  • 3
  • 44
  • 63
2

This function would fix those strings.

$key = 'a b.c[d';
$key = fix_key($key);
$value = 'value';
$_GET[$key] = $value;
print_r($_GET);
echo '<p><a href="' . $_SERVER["REQUEST_URI"] . '?' . $key . '=' . $value . '">test</a></p>';

function fix_key($strKey) {
    $search = array(chr(32), chr(46), chr(91));
    for ($i=128; $i <= 159; $i++) array_push($search, chr($i));
    return str_replace ( $search , '_', $strKey);
}