【问题标题】:PHP PDO MySQL count() prepared statementPHP PDO MySQL count() 准备好的语句
【发布时间】:2016-09-10 11:47:17
【问题描述】:

我正在学习 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;
}

我错了吗?他们是错的还是我们都错/对了?

【问题讨论】:

  • 您应该始终绑定不受信任的参数(几乎是所有参数)。
  • 你完全正确。即使输入是可信的,它仍然可以包含破坏 sql 的字符,因此您应该始终使用准备好的语句并将值绑定到占位符。
  • 我在课堂上提出了这个问题,他们说我是对的,但这不是问题,因为这只是一个工作示例,并不是课程的目的是拥有 20 小时的网络安全.我认为他们为学生提供完全错误和不安全的例子是非常错误的。如果不利用 PDO 的 prepared statements,他们最好使用 mysql_*mysqli_*
  • mysqli_* 也支持预处理语句:P
  • 真的吗? 20小时从一开始就做,也就是准备一个语句并绑定值?!看来你的老师要退休了……

标签: php mysql oop pdo


【解决方案1】:

是的,你是对的。

但是,您的代码不是最优的。事实上,prepared statements 旨在使您的代码更干净,而不是更臃肿。

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();
}

我所做的部分清理只是一个技巧 - 因为您始终可以搜索 LIKE '%%' 并匹配所有行(但不包括 user_name 为 null 的行)。

但剩下的只是正确使用 PDO 特性:

  • 您始终可以使用位置占位符
  • 您始终可以避免调用 bindParam()
  • 您应该使用适当的获取模式

【讨论】:

  • 应该是数组参数:->execute("%$search%");
  • 是的,我知道,我只是让我的培训师的示例少了一些错误。
  • @你的常识,你的The only proper guide on PDO 让我对正确使用 PDO 非常挑剔:)
  • @bsteo 我很高兴听到!顺便说一句,你老师的逻辑有一个通常的缺陷(虽然可以原谅,因为它被 95% 的 PHP 用户共享):准备好的语句的主要目的不是安全性,而仅仅是语法正确性。在搜索字符串中添加引号,即使没有任何有害意图,查询也会失败。虽然安全性是一种副产品。
猜你喜欢
  • 1970-01-01
  • 2010-11-30
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多