我正在进行Web开发课程。使用PHP PDO MySQL,他们在一个研讨会上教我们:
function countUsers($search) {
$and = '';
if ($search != '') {
$and = " AND user_name LIKE '%".$search."%'";
}
$total = $this->db->query("SELECT COUNT(id) as rows FROM users WHERE valid = 1" . $and)->fetch(PDO::FETCH_OBJ);
return $total->rows;
}
从我的观点来看,这是完全错误的,声明没有准备好,直接从用户输入传递而没有任何可以导致SQL注入的验证,所以我向训练师提出了这个(我知道fetchColumn()会是这里更合适,但为了这个例子,我们坚持这一点):
function countUsers($search) {
$and = '';
$sqlSearch = "%$search%";
if ($search != '') {
$and = " AND user_name LIKE :username";
}
$sql = "SELECT COUNT(id) as rows FROM users WHERE valid = 1" . $and;
$sth = $this->db->prepare($sql);
if ($search != '') {
$sth->bindParam(':username', $sqlSearch, PDO::PARAM_STR);
}
$sth->execute();
$total = $sth->fetch(PDO::FETCH_OBJ);
return $total->rows;
}
我错了吗?他们错了还是我们都错了/对吗?
答案 0 :(得分:4)
是的,你是对的。
但是,您的代码并不是最佳的。事实上,准备好的语句旨在使您的代码更清洁,而不是更臃肿。
ipkg install openssl
我所做的部分清理只是一招 - 因为你总是可以搜索function countUsers($search) {
$sql = "SELECT COUNT(id) FROM users WHERE valid = 1 AND user_name LIKE ?";
$sth = $this->db->prepare($sql);
$sth->execute(["%$search%"]);
return $sth->fetchColumn();
}
并匹配所有行(不包括user_name为null的行)。
但其余的只是正确使用PDO功能: