0

我编写了以下函数来构造和执行带有键值绑定的 SQL 语句。我正在使用 bindValue() 将键值对数组绑定到它们在 SQL 字符串中的相应标识符。(回显语句用于调试)。

public function executeSelect($sql, $bindings = FALSE)
{
    $stmt = $this->dbPDO->prepare($sql);

    if ($bindings)
    {
        foreach($bindings as $key => $value)
        {
            $success = $stmt->bindValue($key, $value);
            echo "success = $success, key = $key, value = $value<br />";
            if (!$success)
            {
                throw new Exception("Binding failed for (key = $key) & (value = $value)");
            }
        }
    }

    echo "Beginning execution<br />";
    if ($stmt->execute())
    {
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    else
    {
        return FALSE;   
    }
}

该函数的输入如下:

$stmt = "SELECT * FROM test WHERE id = :id";
$bindings = array(":id" => "3", ":Foo" => "Bar");

在通过 $bindings 数组的第二个循环中,我希望 $success 评估为 false,因此抛出自定义异常,因为“Bar”不能绑定到“ :Foo”,因为“ :Foo”在输入 SQL 中不存在。

相反,对于 $bindings 数组中的两个键值对,$success 的计算结果为 true (1),并且 ->execute() 会抛出 PDOException"(HY000)SQLSTATE[HY000]: General error: 25 bind or column index out of range"

为什么 bindValue 不返回 false?

4

1 回答 1

1

因为它是这样工作的。
它不是在绑定时而是在执行时引发错误。就这样。

所以,不需要循环,你可以让你的方法更短。

public function executeSelect($sql, $bindings = FALSE)
{
    $stmt = $this->dbPDO->prepare($sql);
    $stmt->execute($bindings);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

我相信也不需要检查执行结果。
如果出现错误,它将已经引发异常。

顺便说一句,我会基于这个创建几个辅助函数,返回标量值和单行。他们很有帮助。虽然我发现命名占位符有点乏味。比较这段代码:

$name = $db->getOne("SELECT name FROM users WHERE group=?i AND id=?i",$group,$id);
vs.
$sql = "SELECT name FROM users WHERE group=:group AND id=:id";
$name = $db->getOne($sql,array('group' => $group, 'id' => $id));

命名需要比匿名多 2 倍的代码。
首字母缩略词的完美示例WET- “Write Everything Twice”

于 2013-02-02T05:53:58.460 回答