这类似于这个问题 - Are Dynamic Prepared Statements Bad? (with php + mysqli),但是因为它已经4岁了,我想得到一个更新的答案。
我已经编写了一个类,虽然我没有在更多的copmlex sql查询上测试它,但它在简单的SQL查询上工作顺利,但是我不确定这样做是否绕过了一个主要原因准备好的陈述 - 安全。
我已经使用了call_user_func_array
这对bind_param
语句很容易,但bind_result
有点棘手。我最初使用的是get_result
但是我已经使用的主机没有mysqlnd
可用,但我设法使用元数据。这是我写的全班。
你认为这是安全的吗?
传入的值为:
$sql
是传入的sql语句:
SELECT * FROM users WHERE id = ? AND created_timestamp > ?
$mysqli
是mysqli连接
$para
是预备声明中的占位符:
array ($types = 'ii', 23, 1235376000)
班级:
class crudModel {
function ps($sql, $mysqli, $para) {
//this function should work for just about any simple mysql statement
//for more complicated stuff like joins, unions etc,. we will see
if ($prep = $mysqli->prepare($sql)) {
call_user_func_array(array($prep, 'bind_param'), $this->makeValuesRef($para, $mysqli));
$prep->execute();
$meta = $prep->result_metadata();
while ($field = $meta->fetch_field()) {
$parameters[] = &$row[$field->name];
}
call_user_func_array(array($prep, 'bind_result'), $parameters);
while ($prep->fetch()) {
foreach ($row as $key=>$val) {
$x[$key] = $val;
}
$data[] = $x;
}
return $data;
}
}
function makeValuesRef($array, $mysqli) {
$refs = array();
foreach($array as $key => $value) {
$array[$key] = $mysqli->real_escape_string($value); //i don't think escaping is necessary, but it can't hurt (??)
$refs[$key] = &$array[$key];
}
return $refs;
}
}
答案 0 :(得分:1)
你在这里做的不是动态准备的陈述。你只是把一些合成糖放在MySQLi API之上(很糟糕)。
简而言之,您在此处显示的代码中并未存在任何安全问题。实际上,这种做法非常好,因为它可以更容易地验证您以后正确地执行它(因为MySQLi API很糟糕)。
所以你没事。我会担心您生成查询的区域,并确保您不会在没有白名单的情况下意外地将用户数据放入其中...