首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP将数组传递并内爆到查询占位符

问PHP将数组传递并内爆到查询占位符
EN

Stack Overflow用户
提问于 2013-08-21 09:50:52
回答 1查看 1.4K关注 0票数 1

首先,如果这件事在别的地方被回答了,我很抱歉,但是我什么也找不到。

下面的代码有问题:

代码语言:javascript
复制
function register_user ($register_data) {
    global $db;
    array_walk ($register_data, 'array_sanitize');
    $register_data ['password'] = md5 ($register_data ['password']); 

    $fields = '`' . implode ('`, `', array_keys ($register_data)) . '`';
    $data   = '\'' . implode ('\', \'', $register_data) . '\'';

    $query = $db -> prepare ("INSERT INTO `users` (:fields) VALUES (:data)");
    $query -> bindParam (':fields', $fields);
    $query -> bindParam (':data', $data);
    $query -> execute ();
}

问题是,这是正确的执行,但查询没有运行,行没有插入数据库。

现在,如果我这么做:

代码语言:javascript
复制
$query = $db -> prepare ("INSERT INTO `users` ($fields) VALUES ($data)");
//$query -> bindParam (':fields', $fields);
//$query -> bindParam (':data', $data);
$query -> execute ();

一切都很有魅力,所以我猜问题就在于如何将数据传递给占位符。

有人能给我解释一下为什么这不管用吗?首先,我想正确地理解它。

提前感谢您的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-21 09:53:47

有两种不同的用例可以被描述为将一个内爆数组传递给查询占位符。一种是在SQL中使用带有IN()子句的准备语句。这个案例已经在这个答案中得到了充分的讨论。

另一个用例是插入助手函数,就像您的问题中的一个。我有一篇文章解释了如何创建一个SQL注入验证MYSQL。

考虑到这样的函数不仅向查询添加数据值,而且还添加表名和列名,准备好的语句将不足以保护免受SQL注入的影响。因此,这样的函数将需要自己的助手函数,以保护名为表和字段的字段。下面是MySQL的一个例子:

代码语言:javascript
复制
function escape_mysql_identifier($field){
    return "`".str_replace("`", "``", $field)."`";
}

现在,我们终于可以使用一个函数接受带有数据的表名和数组,并对数据库运行准备好的INSERT查询:

代码语言:javascript
复制
function prepared_insert($pdo, $table, $data) {
    $keys = array_keys($data);
    $keys = array_map('escape_mysql_identifier', $keys);
    $fields = implode(",", $keys);
    $table = escape_mysql_identifier($table);
    $placeholders = str_repeat('?,', count($keys) - 1) . '?';
    $sql = "INSERT INTO $table ($fields) VALUES ($placeholders)";
    $pdo->prepare($sql)->execute(array_values($data));
}

可以这样使用:

代码语言:javascript
复制
prepared_insert($pdo, 'users', ['name' => $name, 'password' => $hashed_password]);

完整的解释可以在上面链接的文章中找到,但是简单地说,我们正在为SQL值()子句创建一个输入数组键的列名列表和一个逗号分隔的占位符列表。最后,我们将输入数组值发送到PDO的execute()中。安全、方便、简洁。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18354216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档