【问题标题】:PDO having optional bind parameters without re-writing SQL query string [duplicate]PDO 具有可选绑定参数而无需重写 SQL 查询字符串 [重复]
【发布时间】:2017-04-17 04:36:17
【问题描述】:

我有一个从反馈表表中选择记录列表的函数。目前查询是基于两个课程 ID 和用户 ID:

$sql = "SELECT * FROM `feedback` WHERE course_id = :course_id AND user_id = :user_id LIMIT 1";
$stmt = $this->ci->db->prepare($sql);
$result = $stmt->execute([
    "course_id" => $course_id,
    "user_id" => $user_id
        ]);
$results = $stmt->fetch(PDO::FETCH_ASSOC);

我想这样做,所以用户 ID 是可选的,但不确定如何最有效地编写它?

例如,我可以这样做:

if ($user_id) {
    $sql = "SELECT * FROM `feedback` WHERE course_id = :course_id AND user_id = :user_id LIMIT 1";
    $stmt = $this->ci->db->prepare($sql);
    $result = $stmt->execute([
         "course_id" => $course_id,
         "user_id" => $user_id
    ]);

 } else {

    $sql = "SELECT * FROM `feedback` WHERE course_id = :course_id LIMIT 1";
    $stmt = $this->ci->db->prepare($sql);
    $result = $stmt->execute([
         "course_id" => $course_id,
    ]);

}

$results = $stmt->fetch(PDO::FETCH_ASSOC);

但这似乎非常低效。问题是如果我省略了"user_id" => $user_id(在第一段代码中),那么我的$sql 是无效的,因为绑定参数的数量不匹配。

解决这个问题的最佳方法是什么?

【问题讨论】:

  • 你不是已经在这里问过同样的问题了吗stackoverflow.com/questions/40525986/…
  • 并非如此。这是一个关于在循环数组时使用LIKE= 条件的问题。真的完全不同。

标签: php mysql pdo


【解决方案1】:

由于您使用的是 $this,我假设您在一个类中,所以我创建了一个函数来包装该过程。 当某些参数是可选的时,我习惯于使用 PHP 字符串连接来构造我的请求。 由于您也可以将条目动态添加到 PDOStatment 使用的参数数组中,因此您可以这样做:

public function getRecords($course_id, $user_id = null) {

    // Init request string
    $request = "SELECT * 
                FROM `feedback` 
                WHERE course_id=:course_id";

    // Init $params array
    $params = array(
        ':course_id'    =>  $course_id
    );

    // If user_id is passed to the function
    // update request string & $params array
    if(null !== $user_id) {
        $request .= " AND user_id=:user_id";
        $params[':user_id'] = $user_id;
    }

    // Finish request
    $request .= " LIMIT 1";

    $stmt = $this->ci->cb->prepare($request);
    $stmt->execute($params);
    $results = $stmt->fetch(PDO::FETCH_ASSOC);
}

【讨论】:

  • 是的,查询在一个类函数中——为简洁起见,我只是省略了这个。谢谢,这将满足我的需求。
  • 它是否可以防止 MySQL 注入?不应该有bindParam吗?如果参数是混合的,比如一些是整数,另一些是字符串呢?
  • 如果你想指定值的类型,那么你可以使用bindParam,因为当你只使用execute($array_or_params)时,所有参数都被处理为字符串。 (更详细的答案在这里:stackoverflow.com/questions/12392424/pdo-bindparam-vs-execute)使用 PDO 和准备好的查询的目的是防止 sql 注入,因为无论您使用什么方法,值都会被转义。
猜你喜欢
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
  • 2010-10-06
  • 1970-01-01
  • 2019-08-15
  • 2011-05-25
  • 2011-11-16
  • 1970-01-01
相关资源
最近更新 更多