当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