检测 PHP 解析多维 POST 数据期间的错误


Detecting errors during PHP's parsing of multidimensional POST data

当PHP将多维数据解析为$_POST时,它命中了它不理解的名称的一部分,它只是使用到目前为止得到的东西。

例如:

<?php
var_dump($_POST);
?>
<form action=# method=post>
<input type=text value='hello' name='a[b]c]'>  <!-- note missing [ before c -->
<input type=submit>
</form>

结果:

array (size=1)
   'a' => 
      array (size=1)
         'b' => string 'hello' (length=5)

检测此类情况的最佳方法是什么,其中"c]"从名称中被丢弃?

我正在使用多维 $_POST 功能来避免自己实现一个,所以理想情况下,我追求的是从 PHP 实现中捕获警告的解决方案。

这个正则表达式是非常基本的,你可以尝试扩展它(或编辑我的帖子)

function get_raw_post(){
    $raw = file_get_contents("php://input");
    return ( strpos('&',$raw) !== false ) ? post_get_associative( explode( '&',$raw ) ) || array();
}
function post_get_associative($post){
    $new = array();
    foreach($post as $key => $val) {
        if (preg_match("/(.'S+'[+.+']+)/", $key,$match)) {
            $new[$match[1]] = $val;
        }else{
            $new = $val;
        }
    }
    return $new;
}

这样使用

$post = get_raw_post();

看起来 PHP 无法在那里生成警告,因此如果不重新编译 PHP,这是不可能的。注1]

我最终使用这样的东西来手动检查:

#print out a list of POST variables from the raw input.  
#Variables where part of the name is discarded by the parser are tagged "BAD".
function abz_post_check() {
    $raw_post_data = file_get_contents("php://input");
    echo "<pre>testing post vars";
    foreach (explode("&", $raw_post_data) as $var) {
        abz_post_var_check($var);
    }
    echo "</pre>";
    var_dump($raw_post_data);
}
function abz_post_var_check($var) {
    if (empty($var)) {
        return;
    }
    if (false !== strpos($var, '=')) {
      list($key, $value) = explode("=", $var);
    } else {
      $key = $var;
      $value = '';
    }
    $key = urldecode($key)
    #pattern matches only
    #  'string-without-['  followed by any number of 'string-in-[]'
    #note that 'string-without-[' is not a precise description of
    #what PHP matches, but it's good enough for my purposes.
    if (!preg_match('/^[^[]+('[[^[']]*'])*$/', $key)) {
        echo "<span style='color: red'> BAD: $key</span>'n";
    } else {
    echo "GOOD: $key'n";
    }
}
abz_post_check();

[1] 我认为 PHP 源代码中的相关代码是php_register_variable_ex()的,它可以显示的唯一警告是"超出输入变量嵌套级别"。 https://github.com/php/php-src/blob/4b943c9c0dd4114adc78416c5241f11ad5c98a80/main/php_variables.c