HTML POST 到 PHP 脚本上的 htmlspecialchar 数组和单个输入

htmlspecialchar on HTML POST to PHP script with array and single inputs

我有一个 HTML 表单,它使用 POST 将数据发送到 PHP 脚本。到目前为止,我还没有在 HTML 表单中使用数组,但此表单要求对某些字段进行分组(例如,价格和数量),而其他字段仍然是单个输入字段(姓名、电子邮件等)。

我想在 PHP 脚本收到输入时对其进行清理。对于单个输入字段,我曾经像这样遍历字段:

if( !empty($_POST) ) {
    foreach( $_POST as $x => $y ) {
        $_POST[$x] = htmlspecialchars($y);
        $_POST[$x] = trim($y);
    }
}

当某些项目在数组中时,如何清理输入?

您需要为此创建一个递归函数。

function htmlentitiesRecursive($data)
{
    if (is_array($data)) {
        // If the data is an array, iterate through it and convert each item
        foreach ($data as $key => $value) {
            $data[$key] = htmlentitiesRecursive($value);
        }

        return $data;
    }

    // If the data is a string, convert it into html entities
    return is_string($data) 
        ? htmlentities(trim($data))
        : $data;
}

用法:

$_POST = htmlentitiesRecursive($_POST);

使用本机函数 array_walk_recursive() 可以轻松修改多维数组中的所有叶节点,因为它按设计访问了所有 "leaf nodes"。

代码:(Demo) (or as an anonymous one-liner)

$sweet = ['a' => 'apple ', 'b' => ' "banana"      '];
$array = ['sweet' => $sweet, 'test' => " <a href='test'>Test</a>"];

function mySanitizer(&$value) {
    $value = htmlspecialchars(trim($value));
}
array_walk_recursive($array, 'mySanitizer');

var_export($array);

输出:

array (
  'sweet' => 
  array (
    'a' => 'apple',
    'b' => '&quot;banana&quot;',
  ),
  'test' => '&lt;a href=\'test\'&gt;Test&lt;/a&gt;',
)

注意在 value 参数上使用 &。这告诉脚本通过引用修改数据——否则在 array_walk_recursive

的范围之外不会有任何更改。

如何应用此技术...

要将此技术应用于 $_POST 超全局数组中的所有元素,请调用:

array_walk_recursive($_POST, 'mySanitizer');

当然,这需要您编写自定义函数声明(function mySanitizer() {...})。

或者,如果您不想声明自定义函数 mySanitizer,那么您只需要这样写:

array_walk_recursive($_POST, function(&$value){
    $value = htmlspecialchars(trim($value));
});

大多数函数的 return 值更为常见,但是 array_walk_recursive() 不提供 return 数据。为了使此函数对您的要求有效,输入数组必须直接受其包含的自定义函数的影响。 "Modifying a variable by reference" 意味着您不需要通过赋值覆盖 $_POST 变量(如 $_POST = ...)。只需将输入数组输入本机函数,在 $value 参数之前写入 &,然后在迭代时覆盖每个遇到的 $value,您的 $_POST 变量将被清理。

至于如何array_walk_recursive() "iterates/loops"...有一个特殊的行为享受。该函数将遍历数组的每一层。如果找到 "iterable" 元素,它将遍历它包含的元素。如果遇到不可迭代的元素(标量元素可能是字符串、整数、浮点数、布尔值、空值),它将对其执行函数/回调(无论你命令它做什么)。

通过引用修改的 php 函数的另一个示例是 sort()。您不需要使用此函数进行赋值,您只需将数据传递给它,当您下次访问变量的数据时,它已经被修改了。