我有一个模块,允许管理员将一些用户(可能是多个)添加到组中。
PHP
$user_id = $_POST["user_id"]; //this can be an array
$group_id = $_POST["group_id"];
$sql = "INSERT IGNORE INTO users_groups (user_id, group_id)
VALUES ($user_id[0],$group_id)";
for ( $i = 1; $i < count($user_id); $i++)
{
$sql .= ", ($user_id[$i],$group_id)"
}
正如您所看到的,sql-query取决于管理员选择了多少用户。
如何将此代码与预准备语句一起使用,因为后变量来自用户(SQL注入......)
更新
我有两个选择框:
$_POST["user_id"]
$_POST["group_id"]
现在我想要一个准备好的SQL语句,用于将user_id
和group_id
插入到多对多表(users_groups
)。问题是必须插入的值的数量可以更改(取决于管理员在选择框中选择了多少用户)。
我想根据管理员选择的用户数量来更改准备好的查询。
例如:
INSERT IGNORE INTO users_groups (user_id, group_id) VALUES ($user_id[0],$group_id), ($user_id[1],$group_id)
INSERT IGNORE INTO users_groups (user_id, group_id) VALUES ($user_id[0],$group_id), ($user_id[1],$group_id), ($user_id[2],$group_id), ($user_id[3],$group_id)
我的问题:我怎么能自动完成这个并使用准备好的sql语句,因为我不希望有10次if(count($user_id) == number) {...
?
更新2 如果我手动执行此操作,代码将如下所示:
$sql = $db->prepare("INSERT IGNORE INTO users_groups (user_id, group_id) VALUES (?, ?)");
$sql->bind_param('ii', $user_id[0], $group_id);
更新3 检查post变量中是否只有整数:
$user_id = filter_input_array(INPUT_POST, 'user_id', FILTER_SANITIZE_NUMBER_INT);
$user_id = abs($user_id);
$group_id = filter_input(INPUT_POST, 'group_id', FILTER_SANITIZE_NUMBER_INT);
$group_id = abs($group_id);
答案 0 :(得分:2)
要创建SQL语句,您可以使用它来生成所有user_id值所需的占位符。
$user_ids = $_POST["user_id"]; //this can be an array
$group_id = $_POST["group_id"];
$placeholders = implode(', ', array_fill(0, count($user_ids), "(?, ?)"));
$sql = "INSERT IGNORE INTO users_groups (user_id, group_id) VALUES $placeholders";
然后绑定值,如果你使用pdo,这样的东西应该可以工作:
$stmt = $pdo->prepare($sql);
$i = 1;
foreach ($user_ids as $user_id) {
$stmt->bindValue($i++, $user_id);
$stmt->bindValue($i++, $group_id);
}
或者,如果你使用的是mysqli,你可以尝试使用反射这种方法(取自php docs here中的用户注释),注释确实说明这需要PHP 5.3+,希望你有。
$stmt = $mysqli->prepare($sql);
$values[] = str_repeat('ii', count($user_ids));
foreach ($user_ids as $user_id) {
$values[] = $user_id;
$values[] = $group_id;
}
$ref = new ReflectionClass('mysqli_stmt');
$method = $ref->getMethod("bind_param");
$method->invokeArgs($stmt, $values);
$stmt->execute();
或者,因为我顽固而且来自php docs用户注释的内容似乎无法正常工作,经过阅读后我不知道它是如何工作的,考虑到php doc ReflectionMethod::invokeArgs特别说
注意:如果函数的参数需要引用,那么它们必须是传递的参数列表中的引用。
然后使用call_user_func_array
可能会有效。
$stmt = $mysqli->prepare($sql);
$type = str_repeat('ii', count($user_ids));
foreach ($user_ids as $user_id) {
$values[] = $user_id;
$values[] = $group_id;
}
foreach ($values as $key => $value) {
$value_references[$key] = &$values[$key];
}
call_user_func_array('mysqli_stmt_bind_param',
array_merge(array($stmt, $type), $value_references));
但是多么痛苦。我真的很喜欢pdo。