如何在PHP中将urlencoded查询字符串解析为数组(不更改名称)

时间:2014-11-25 23:58:29

标签: php

我知道你在想什么。 “我可以这么快回答这个问题!这是parse_str功能!”但是我有点麻烦。

您会看到,PHP会将所有查询数据的名称转换为有效的PHP变量名称。什么?即使他们没有被存储为变量?记录在哪里?事实并非如此。

$payload = 'data.name=value&data.other=value2';
parse_str($payload, $values);
var_export($values);
// Outputs:  array('data_name' => 'value', 'data_other' => 'value2')
// Expected: array('data.name' => 'value', 'data.other' => 'value2')

如何在不发生的情况下解析查询字符串

2 个答案:

答案 0 :(得分:2)

您可以通过自己解析查询字符串来避免PHP重命名参数名称。将字符串拆分为&=字符,然后urldecode()各个部分:

<?php

  $payload = 'data.name=value&data.other=value2';

  $values = array();

  $nv_strings = explode ('&', $payload);
  foreach ($nv_strings as $s) {
    $nv = explode ('=', $s, 2);
    $name = urldecode ($nv[0]);
    $value = (isset ($nv[1]) ? urldecode ($nv[1]) : null);
    $values[$name] = $value;
  }

  print_r ($values);

//  Array
//  (
//      [data.name] => value
//      [data.other] => value2
//  )

如果您的查询字符串包含重复的键,则上述代码将覆盖以前的键。这也可以解决:

<?php

  $payload = 'key=val1&key=val2&key=val3';

  $values = array();

  $nv_strings = explode ('&', $payload);
  foreach ($nv_strings as $s) {
    $nv = explode ('=', $s, 2);
    $name = urldecode ($nv[0]);
    $value = (isset ($nv[1]) ? urldecode ($nv[1]) : null);
    $values[] = array ($name => $value);
  }

  print_r ($values);

//  Array
//  (
//      [0] => Array ([key] => val1)
//      [1] => Array ([key] => val2)
//      [2] => Array ([key] => val3)
//  )

您可能希望将重复键合并到子数组中:

<?php

  $payload = 'key1=val1&key1=val2&key2=val3';

  $values = array();

  $nv_strings = explode ('&', $payload);
  foreach ($nv_strings as $s) {
    $nv = explode ('=', $s, 2);
    $name = urldecode ($nv[0]);
    $value = (isset ($nv[1]) ? urldecode ($nv[1]) : null);
    if (isset ($values[$name])) {
      if (is_array ($values[$name])) {
        $values[$name][] = $value;
      } else {
        $values[$name] = array ($values[$name], $value);
      }
    } else {
      $values[$name] = $value;
    }
  }

  print_r ($values);

//  Array
//  (
//      [key1] => Array ([0] => val1
//                       [1] => val2)
//      [key2] => val3
//  )

您可以通过始终使用子数组来简化代码:

<?php

  $payload = 'key1=val1&key1=val2&key2=val3';

  $values = array();

  $nv_strings = explode ('&', $payload);
  foreach ($nv_strings as $s) {
    $nv = explode ('=', $s, 2);
    $name = urldecode ($nv[0]);
    $value = (isset ($nv[1]) ? urldecode ($nv[1]) : null);
    if (isset ($values[$name])) {
      $values[$name][] = $value;
    } else {
      $values[$name] = array ($value);
    }
  }

  print_r ($values);

//  Array
//  (
//      [key1] => Array ([0] => val1
//                       [1] => val2)
//      [key2] => Array ([0] => val3)
//  )

答案 1 :(得分:0)

在PHP文档中完全记录了函数parse_str如果输出不适合您的特定用例,那么您必须使用其他函数,或创建自己的函数。这里的关键是这个函数将字符串解析为变量。

  

parse_str - 将字符串解析为变量   解析str,好像它是通过URL传递的查询字符串,并在当前范围中设置变量。

要解析您提供的字符串,这将起作用:

$payload = 'data.name=value';
$map = array();
$vals = preg_split('/=/', $payload);
$i= 0;
while($i < count($vals)) {
  $map[$vals[$i]] = $vals[++$i];
  $i++;
}

var_dump($map);