将“true或false”绑定为PDO参数

时间:2012-03-02 01:30:15

标签: php pdo

我有一个MySQL列'public',它包含布尔值(aka tinyint,1或0)。查询时我通常不关心公共列的值,所以默认情况下我传递一个下划线(MySQL通配符)。在某些情况下,虽然我只想要匹配“public = 0”或“public = 1”的行,所以我用0或1覆盖下划线。这不是我给过的最清晰的解释,所以这里有一些代码:

public function get_hunts($public = '_') {
  $sth = $this->_db->prepare("SELECT * FROM hunts WHERE( user_id = :user AND public = :public)");
  $sth->bindParam(':user', $this->_id);
  $sth->bindParam(':public', $public);
  $sth->execute();
  $result = $sth->fetchAll(PDO::FETCH_ASSOC);

  return $result;
}

//get any result
get_results();

//get only public results
get_hunts(1)

以这种方式绑定下划线(我也尝试过通用通配符%)会导致查询失败。有什么更好的方法来实现这一目标?

2 个答案:

答案 0 :(得分:3)

要使用任何通配符,您需要使用LIKE比较而不是等于

AND public LIKE :public

否则,您需要采用某种查询构建器方法,根据函数的参数构建WHERE条件。

public function get_hunts($public = null) {
    $where = array(
        'user_id = :user'
    );
    $params = array(
        ':user' => $this->_id
    );

    if (null !== $public) {
        $where[] = 'public = :public';
        $params[':public'] = (boolean) $public;
    }

    $query = 'SELECT * FROM hunts WHERE ' . implode(' AND ', $where);
    $sth = $this->_db->prepare($query);
    $sth->execute($params); // same as binding

    return $sth->fetchAll(PDO::FETCH_ASSOC);
}

答案 1 :(得分:3)

绑定参数仅适用于简单文字,因此您无法绑定表格和列名称(标识符)或IN子句(文字列表)等内容。

所以你想要的东西不可能直截了当。

你真正应该做的是使用不同的查询:

function get_hunts($public=null) {
    // assuming hunts.public is defined as NOT NULL
    $sql = "SELECT * FROM hunts WHERE user_id=:user";
    if ($public!==null) {
       $sql .= ' AND public=:public';
    }
    $sth  = $this->_db->prepare($sql);
    $sth->bindParam(':user', $this->_id);
    if ($public!==null) {
        $sth->bindParam(':public', $public, PDO::PARAM_INT);
    }
    $sth->execute();
    return $sth->fetchAll(PDO::FETCH_ASSOC);
}

如果您确实不想使用其他查询,则可以使用带有CASE表达式的hacky解决方案。

SELECT * FROM hunts WHERE user_id=:user
  AND public=
    CASE :public WHEN 0 THEN 0 WHEN 1 THEN 1 ELSE public END

如果绑定的值不是0或1,则WHERE条件将要求public等于自身,因此始终为true。否则,使用:public的值。