【问题标题】:htmlspecialchar on HTML POST to PHP script with array and single inputshtmlspecialchar on HTML POST to PHP script with array and single inputs
【发布时间】:2020-03-25 16:03:18
【问题描述】:

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

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

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

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

【问题讨论】:

  • 你打算用上面的值做什么?通常建议将值保持“原样”,直到您要使用它(例如在输出值时使用 htmlentities() ,而不是在接收时使用)。然后您可以将这些数据用于不同的事情,而不仅仅是用于输出 HTML。
  • 该表格将发送一封包含订单信息的电子邮件。我正在努力防止注射。

标签: php arrays forms post htmlspecialchars


【解决方案1】:

使用本机函数array_walk_recursive() 可以轻松修改多维数组中的所有叶节点,因为它通过设计访问所有“叶节点”。

代码:(Demo)(或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 参数上使用 &amp;。这告诉脚本通过引用来修改数据——否则不会在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() 不提供返回数据。要使此函数有效满足您的要求,输入数组必须直接受其包含的自定义函数的影响。 “通过引用修改变量”意味着您不需要通过赋值覆盖$_POST 变量(如$_POST = ...)。只需将输入数组输入到本机函数中,在$value 参数之前写入&amp;,然后在迭代时覆盖每个遇到的$value,您的$_POST 变量就会被清理。

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

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

【讨论】:

  • @Magnus 更好的建议是不要重新发明原生函数。
  • 感谢您的更新。我是新来的。人们在接受答案之前允许的典型等待时间是多少?
  • @chilly 这变化很大,我说不出什么是典型的。如果出现更好的答案,可以移动绿色勾号。一些提问者对移动绿色勾号感到不舒服。如果您等待一天左右,您就可以让来自不同时区的志愿者有机会阅读您的问题。
  • 谢谢。我想更好地理解你的答案,而且我对 PHP 不是很有经验。你能把它放在 POST 的上下文中吗?有了 Magnus 的回答,我马上就可以应用了。
  • 感谢您添加解释。这对我来说是完美的!
【解决方案2】:

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

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);

【讨论】:

    猜你喜欢
    • 2021-08-18
    • 2013-08-13
    • 2012-10-15
    • 2023-03-10
    • 2022-12-19
    • 2022-12-02
    • 2022-04-20
    • 2022-12-28
    • 2016-02-12
    相关资源
    最近更新 更多