在PHP中检查每个数组索引真的有多重要?

我正在开发一个相当大的项目,其中有很多地方存在以下代码:
function foo($a, $b, $c, $d, $e, $f) {
    $clean = array();
    $mysql = array();

    $clean['a'] = htmlentities($a);
    $clean['b'] = htmlentities($b);
    $clean['c'] = htmlentities($c);
    $clean['d'] = htmlentities($d);
    //...

    $mysql['a'] = mysql_real_escape_string($clean['a']);
    $mysql['b'] = mysql_real_escape_string($clean['b']);
    $mysql['c'] = mysql_real_escape_string($clean['c']);
    $mysql['d'] = mysql_real_escape_string($clean['d']);
    //...

    //construct and execute an SQL query using the data in $mysql
    $query = "INSERT INTO a_table
              SET a='{$mysql['a']}',
                  b='{$mysql['b']}',
                  c='{$mysql['c']}',
                  d='{$mysql['d']}'";
}
显然,这会在PHP中针对未定义的索引引发很多警告。 是否真的有必要重写代码如下?
function foo($a, $b, $c, $d, $e, $f) {
    $clean = array();
    $mysql = array();

    $clean['a'] = htmlentities($a);
    $clean['b'] = htmlentities($b);
    $clean['c'] = htmlentities($c);
    $clean['d'] = htmlentities($d);
    //...

    $mysql['a'] = (isset($clean['a'])) ? mysql_real_escape_string($clean['a']) : mysql_real_escape_string($a);
    $mysql['b'] = (isset($clean['b'])) ? mysql_real_escape_string($clean['b']) : mysql_real_escape_string($b);
    $mysql['c'] = (isset($clean['c'])) ? mysql_real_escape_string($clean['c']) : mysql_real_escape_string($c);
    $mysql['d'] = (isset($clean['d'])) ? mysql_real_escape_string($clean['d']) : mysql_real_escape_string($d);
    //...

    //construct and execute an SQL query using the data in $mysql
    if (isset($mysql['a']) and isset($mysql['b']) and isset($mysql['c']) and isset($mysql['d'])) {
        $query = "INSERT INTO a_table
                  SET a='{$mysql['a']}',
                      b='{$mysql['b']}',
                      c='{$mysql['c']}',
                      d='{$mysql['d']}'";
    }

}
    
已邀请:
如果您使用以下内容,可以大大简化您的功能:
function foo($a, $b, $c, $d, $e, $f) {

    $args = func_get_args();   // or build an array() manually

    $args = array_map("htmlentities", $args);
    $args = array_map("mysql_real_escape_string", $args);

    list($a, $b, $c, $d, $e, $f) = $args;
显示位置的isset()检查似乎完全没用。变量已经定义。     
是否有必要拥有这样的硬编码功能? 我用这个:
function insert_array($table, $data) {  
    $cols = '(';
    $values = '(';
    foreach ($data as $key=>$value) { 
        $value = mysql_real_escape_string($value);
        $cols .= "$key,";  
        $values .= "'$value',";  
    }
    $cols = rtrim($cols, ',').')';
    $values = rtrim($values, ',').')';  
    $sql = "INSERT INTO $table $cols VALUES $values";
    mysql_query($sql) or die(mysql_error());
}
然后插入数据,无论其名称和列如何使用:
$data = array('id' => 1, 'name' => 'Bob', 'url' => 'foo.com');
insert_array('users', $data);
    
是的,如果数组索引或变量不存在,则php发出警告/通知。 正确的方法是在使用
isset()
函数之前检查每个变量。 在使用之前检查它们是一个好习惯。     
您需要检查可能存在或可能不存在的索引。但是,您的代码非常混乱,您的真实代码看起来可能完全不同。在这个示例代码中,键显然存在,您只是自己创建它们。 在您的示例中,您可以将mysql_real_escape_string部分移动到if中检查变量的位置,然后您就已经知道它们存在了。 这里没有理由使用数组,您可以将它们存储在同一个变量中。 XSS-Protection(htmltentities(),请注意这还不够)应该在显示数据之前完成,而不是像在示例中那样存储之前。只有一个原因是你最终会得到多次编码/转义的东西。恶意HTML / JS对您的数据库没有任何伤害。     
如果您的项目非常大,那么未定义的索引可能会成为一个噩梦,特别是如果它们保存用户输入生成的数据,并且特别是在没有带有堆栈跟踪的良好错误报告的情况下。这是因为当数据在请求之间传递时,无法保证它是在其原始入口点设置的,因此您最终会对空值或空值进行大量冗余检查。 您可能希望通过将此功能转换为对象来检查您在此处尝试完成的内容是否可能无法实现。使用$ a $ b和$ c表示的值可以很容易地转换为对象属性,一个save()方法可以将状态保存到数据库。 除此之外,您可以使用foreach循环更快速,更连贯地执行检查。只需通过其键遍历数据,并在循环体内执行真正的转义和htmlentities。 http://php.net/manual/en/control-structures.foreach.php 我还建议使用HTMLPurifier进行XSS过滤,因为很多时候htmlentites是不容易的,特别是对于接受用户内容放在Web应用程序中的公共表单。 http://htmlpurifier.org/     

要回复问题请先登录注册