我被告知下面的查询非常容易被SQL注入 - 我应该使用绑定参数,
class search
{
public $mysqli = null;
public function __construct($mysqli,$keyword = null)
{
$this->mysqli = $mysqli;
}
public function get_result($parameter)
{
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = '".$parameter."'
ORDER BY cnt_id DESC
";
$item = $this->mysqli->fetch_assoc($sql);
return $item;
}
}
我可以问 - 如何用准备好的约束语句来转换这个search
类?
我在线阅读了一些文章,为什么我们应该使用准备好的陈述, article 1 article 2
但我仍然不知道如何改进我的查询......我尝试了下面的修正案,
class search
{
public $mysqli = null;
public function __construct($mysqli)
{
$this->mysqli = $mysqli;
}
public function get_result($parameter)
{
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = '?'
ORDER BY cnt_id DESC
";
$stmt = $this->mysqli->prepare($sql);
/* bind parameters for markers */
$stmt->bind_param("s", $parameter);
/* execute query */
$stmt->execute();
/* fetch value */
return $stmt->fetch();
}
}
因此,当我将搜索类称为对象时,
$mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$output = new search($mysqli);
print_r($output->get_result('1'));
我会收到此错误,
警告:mysqli_stmt :: bind_param() [mysqli-stmt.bind-param]:数量 变量与数量不匹配 准备好的声明中的参数 C:\ wamp \ www \ xxxl \ class_database.php on 第487行
第487行是指$stmt->bind_param("s", $parameter);
感谢。
答案 0 :(得分:1)
尝试删除'
占位符周围的?
。
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
ORDER BY cnt_id DESC
";
在准备好的语句中,整个事情是关于在绑定它时指定param的类型,而不是在SQL查询中 - 当你写'?'
时你做了。您已经说过,当您将param绑定为字符串时,必须是字符串,但不是必需的。数据库引擎现在将如何插入/转义该值。
答案 1 :(得分:0)
这是我在网上搜索后的解决方案:
class search
{
public $mysqli = null;
public function __construct($mysqli)
{
$this->mysqli = $mysqli;
}
public function get_result($parameter)
{
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
ORDER BY cnt_id DESC
";
# create a prepared statement
$stmt = $this->mysqli->prepare($sql);
# bind parameters for markers
$stmt->bind_param("s", $parameter);
# execute query
$stmt->execute();
/*
# these lines of code below return multi-dimentional array, similar to mysqli::fetch_all()
$stmt->store_result();
$variables = array();
$data = array();
$meta = $stmt->result_metadata();
while($field = $meta->fetch_field())
$variables[] = &$data[$field->name]; // pass by reference
call_user_func_array(array($stmt, 'bind_result'), $variables);
$i=0;
while($stmt->fetch())
{
$array[$i] = array();
foreach($data as $k=>$v)
$array[$i][$k] = $v;
$i++;
}
return $array;
*/
# these lines of code below return one dimentional array, similar to mysqli::fetch_assoc()
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$var = $field->name;
$$var = null;
$parameters[$field->name] = &$$var;
}
call_user_func_array(array($stmt, 'bind_result'), $parameters);
while($stmt->fetch())
{
return $parameters;
//print_r($parameters);
}
# the commented lines below will return values but not arrays
# bind result variables
//$stmt->bind_result($id);
# fetch value
//$stmt->fetch();
# return the value
//return $id;
# close statement
$stmt->close();
}
}
虽然不太明白......
我发现很难理解和练习准备和绑定语句... mysqli :: query()更容易让我理解......