阻止PHP在$ _POST超全局中创建数组

时间:2012-12-03 22:39:39

标签: php html forms superglobals

PHP会自动转换

<input type="text" name="foo[0]" value="x" />
<input type="text" name="foo[1]" value="y" />

$_POST['foo'] = array(
    0 => 'x', 
    1 => 'y'
);

大多数时候你都想要这个。但是,在这种情况下,我希望不会发生这种情况。反正告诉PHP不要这样做吗?

我意识到我可以自己解析php://input,但如果我可以避免,我宁愿不这样做。

我也没有重命名输入名称的选项。

4 个答案:

答案 0 :(得分:9)

使用括号[]明确告诉PHP创建数组,不要使用括号:

<input type="text" name="foo_0" value="x" />
<input type="text" name="foo_1" value="y" />

字段将在$ _POST数组中以$_POST['foo_0']$_POST['foo_1']的形式提供。

如果你对标记没有影响(这很奇怪,因为你总是可以改变它们的客户端),你需要压扁数组。

$post = array();

foreach ($_POST as $key => $value) {
    if (!is_array($value)) {
        $post[$key] = $value;
    } else {
        foreach ($value as $foo => $item) {
            $post[$foo] = $item;
        }
    }
}

或阅读一些great input on array flattening

答案 1 :(得分:2)

我不认为你可以在不重新编译php的情况下禁用此功能。

我想通过走多dim数组来警告你重建原始变量名。您无法完全重建名称,因为php会重命名某些字符。例如,php不允许$ _POST / $ _ GET / etc中的顶级数组键中的某些字符...因此它用下划线替换char。这使得无法区分a.b a b a[b,因为它们都显示为a_b。此外,与解析导致此行为的请求变量的数组语法相关的长期错误。这是我几年前提交的一份错误报告https://bugs.php.net/bug.php?id=48597,不太可能修复。

此外,如果启用了该设置,magic_quotes_gpc已将其爪子沉入数组键中。

但如果您对上述边缘情况失败感到满意,那么您可以按如下方式重建数组:

$ritit = new RecursiveIteratorIterator(new RecursiveArrayIterator($_POST));
$result = array();
foreach ($ritit as $k => $leafValue) {
    if ($ritit->getDepth() > 0) {
        $path = array($ritit->getSubIterator(0)->key());
        foreach (range(1, $ritit->getDepth()) as $depth) {
            $path[] = sprintf('[%s]', $ritit->getSubIterator($depth)->key());
        }
        $result[ join('', $path) ] = $leafValue;
    } else {
        $result[$k] = $leafValue;
    }
}


print_r($result);

答案 2 :(得分:0)

恢复数组转换应该像这样:

$POST = array('foo' => array('bar', 'baz'));

foreach ($POST['foo'] as $key => $value) {
    $POST['foo['.$key.']'] = $value;
}
unset($POST['foo']);

var_dump($POST);

输出:

array(2) {
  'foo[0]' =>
  string(3) "bar"
  'foo[1]' =>
  string(3) "baz"
}

答案 3 :(得分:0)

我最终采用了markus-tharkun提出的扁平化方法。对于那些感兴趣的人,这是我最终使用的代码:

function flatten($model) {
    $repeat = false;
    foreach ($model as $name => $value) {
        if (is_array($value)) {
            $repeat = true;
            foreach ($value as $sub_name => $sub_value) {
                $model["{$name}[$sub_name]"] = $sub_value;
            }
            unset($model[$name]);
        }
    }
    if ($repeat) {
        $model = flatten($model);
    }
    return $model;
}