Получить PHP, чтобы остановить замену "." символы в массивах $ _GET или $ _POST? - PullRequest
69 голосов
/ 16 сентября 2008

Если я передаю переменные PHP с . в именах через $ _GET, PHP автоматически заменяет их _ символами. Например:

<?php
echo "url is ".$_SERVER['REQUEST_URI']."<p>";
echo "x.y is ".$_GET['x.y'].".<p>";
echo "x_y is ".$_GET['x_y'].".<p>";

... выводит следующее:

url is /SpShipTool/php/testGetUrl.php?x.y=a.b
x.y is .
x_y is a.b.

... у меня такой вопрос: есть ли какой-либо способ, которым я могу остановить это? Не могу на всю жизнь понять, что я сделал, чтобы заслужить это

PHP-версия, с которой я работаю - 5.2.4-2ubuntu5.3.

Ответы [ 13 ]

0 голосов
/ 16 ноября 2015

Мое текущее решение (основано на предыдущих ответах):

function parseQueryString($data)
{
    $data = rawurldecode($data);   
    $pattern = '/(?:^|(?<=&))[^=&\[]*[^=&\[]*/';       
    $data = preg_replace_callback($pattern, function ($match){
        return bin2hex(urldecode($match[0]));
    }, $data);
    parse_str($data, $values);

    return array_combine(array_map('hex2bin', array_keys($values)), $values);
}

$_GET = parseQueryString($_SERVER['QUERY_STRING']);
0 голосов
/ 06 октября 2014

Используя crb, я хотел воссоздать массив $_POST в целом, хотя имейте в виду, что вам все равно придется убедиться, что вы правильно и кодируете кодирование как на клиенте, так и на сервере. Важно понимать, когда символ действительно недействителен и действительно действителен . Кроме того, люди должны все еще и всегда экранировать данные клиента перед использованием их с любой командой базы данных без исключения .

<?php
unset($_POST);
$_POST = array();
$p0 = explode('&',file_get_contents('php://input'));
foreach ($p0 as $key => $value)
{
 $p1 = explode('=',$value);
 $_POST[$p1[0]] = $p1[1];
 //OR...
 //$_POST[urldecode($p1[0])] = urldecode($p1[1]);
}
print_r($_POST);
?>

Я рекомендую использовать это только для отдельных случаев, но я не уверен насчет отрицательных моментов, если поместить это в начало вашего основного файла заголовка.

0 голосов
/ 12 сентября 2014

Хорошо, функция, которую я включил ниже, "getRealPostArray ()", не очень удобное решение, но она обрабатывает массивы и поддерживает оба имени: "alpha_beta" и "alpha.beta":

  <input type='text' value='First-.' name='alpha.beta[a.b][]' /><br>
  <input type='text' value='Second-.' name='alpha.beta[a.b][]' /><br>
  <input type='text' value='First-_' name='alpha_beta[a.b][]' /><br>
  <input type='text' value='Second-_' name='alpha_beta[a.b][]' /><br>

тогда как var_dump ($ _ POST) выдает:

  'alpha_beta' => 
    array (size=1)
      'a.b' => 
        array (size=4)
          0 => string 'First-.' (length=7)
          1 => string 'Second-.' (length=8)
          2 => string 'First-_' (length=7)
          3 => string 'Second-_' (length=8)

var_dump (getRealPostArray ()) создает:

  'alpha.beta' => 
    array (size=1)
      'a.b' => 
        array (size=2)
          0 => string 'First-.' (length=7)
          1 => string 'Second-.' (length=8)
  'alpha_beta' => 
    array (size=1)
      'a.b' => 
        array (size=2)
          0 => string 'First-_' (length=7)
          1 => string 'Second-_' (length=8)

Функция, за которую она стоит:

function getRealPostArray() {
  if ($_SERVER['REQUEST_METHOD'] !== 'POST') {#Nothing to do
      return null;
  }
  $neverANamePart = '~#~'; #Any arbitrary string never expected in a 'name'
  $postdata = file_get_contents("php://input");
  $post = [];
  $rebuiltpairs = [];
  $postraws = explode('&', $postdata);
  foreach ($postraws as $postraw) { #Each is a string like: 'xxxx=yyyy'
    $keyvalpair = explode('=',$postraw);
    if (empty($keyvalpair[1])) {
      $keyvalpair[1] = '';
    }
    $pos = strpos($keyvalpair[0],'%5B');
    if ($pos !== false) {
      $str1 = substr($keyvalpair[0], 0, $pos);
      $str2 = substr($keyvalpair[0], $pos);
      $str1 = str_replace('.',$neverANamePart,$str1);
      $keyvalpair[0] = $str1.$str2;
    } else {
      $keyvalpair[0] = str_replace('.',$neverANamePart,$keyvalpair[0]);
    }
    $rebuiltpair = implode('=',$keyvalpair);
    $rebuiltpairs[]=$rebuiltpair;
  }
  $rebuiltpostdata = implode('&',$rebuiltpairs);
  parse_str($rebuiltpostdata, $post);
  $fixedpost = [];
  foreach ($post as $key => $val) {
    $fixedpost[str_replace($neverANamePart,'.',$key)] = $val;
  }
  return $fixedpost;
}
...