【发布时间】:2012-07-05 14:28:35
【问题描述】:
这类似于这个问题 - Are Dynamic Prepared Statements Bad? (with php + mysqli),但是因为它已经 4 岁了,我想得到一个更新的答案。
我写了一个类,虽然我没有在更多的 coplex 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;
}
}
【问题讨论】:
-
$sql来自哪里? -
如果您使用 PDO 而不是 mysqli,您的代码将变得更加可移植,因为 PDO 对象层与大多数 DBMS 兼容,而不仅仅是 MySql。
-
$sql 来自另一个类。目前我只使用简单的 sql 语句来测试这个类,连接是我用过的最复杂的东西。即 $sql = "SELECT * FROM users INNER JOIN others ON (users.id = others.user_id) WHERE others.id = ?"
-
刚刚开始使用 PDO,所以也会研究一下
-
但是
$sql起源是从哪里来的呢?它是否 100% 在您的控制之下,并且您可以确定没有恶意 SQL 被注入其中?或者它的某些部分(可能是表或列标识符)是否源自您的应用程序外部?
标签: php mysql security prepared-statement