简写PDO查询

时间:2016-05-28 23:21:37

标签: php mysql pdo

目前,要使用PDO执行查询,我使用以下代码行:

$sql = "SELECT * FROM myTable WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':id', $id);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

经过一些研究,我找到了一种执行相同命令的简短方法:

$stmt_test = $conn->prepare("SELECT * FROM status WHERE status_id = ?");
$stmt_test->execute([$id])->fetchAll(PDO::FETCH_ASSOC);
$result = $stmt_test->fetchAll(PDO::FETCH_ASSOC);

从那里我想我可以使用以下代码缩短它:

$stmt_test = $conn->prepare("SELECT * FROM status WHERE status_id = ?");
$result = $stmt_test->execute([$id])->fetchAll(PDO::FETCH_ASSOC);

但是我收到以下错误:

  

致命错误:在非对象中调用成员函数fetchAll()   第20行/home/.../index.php

问题:为什么我收到此错误?根据我的理解,$stmt_test->execute([$id])应首先执行,然后结果将执行->fetchAll(PDO::FETCH_ASSOC)并从那里返回数组$result,但由于错误发生,必须有一些东西在我的逻辑中有缺陷。我究竟做错了什么?此外,有没有人知道一个更好的速记方法来执行以前的查询?

5 个答案:

答案 0 :(得分:6)

所以你已经得到了“为什么我收到这个错误”这个问题的答案,但没有得到一个“速记PDO查询”。

为此,我们需要一些称为“编程”的东西。

关于编程的一个有趣的事情是我们不仅限于现有的工具,就像其他职业一样。通过编程,我们总是可以创建自己的工具,然后开始使用它而不是旧的工具。

面向对象编程特别适合它,因为我们可以使用现有对象并添加一些功能,其余部分保留原样。

例如,假设我们想要一种在PDO中运行准备好的查询的简便方法。我们所需要的只是使用新的速记方法扩展PDO对象。最难的部分是给新方法起一个名字。

其余的很简单:you need only few lines of code

class MyPDO extends PDO
{
    public function run($sql, $bind = NULL)
    {
        $stmt = $this->prepare($sql);
        $stmt->execute($bind);
        return $stmt;
    }
}

这是您需要的所有代码。您可以将其存储在存储数据库凭据的同一文件中。请注意,此添加不会以任何方式影响您现有的代码 - 它保持完全相同,您可以像往常一样继续使用所有现有的PDO方法。

现在你必须在PDO构造函数中只更改2个字母,将其称为

$conn = new MyPDO(...the rest is exactly the same...);

立即开始使用闪亮的新工具:

$sql = "SELECT * FROM myTable WHERE id = :id";
$result = $conn->run($sql, ['id' => $id])->fetchAll(PDO::FETCH_ASSOC);

或者,给它一些优化,

$result = $conn->run("SELECT * FROM myTable WHERE id = ?", [$id])->fetchAll();

因为您总是可以为所有人设置一次默认提取模式,而对于单个变量,命名占位符没有用处。与接受的答案

相比,这使得此代码成为真正的简写
$stmt_test = $conn->prepare("SELECT * FROM status WHERE status_id = ?");
$stmt_test->execute([$id]);
$result = $stmt_test->fetchAll(PDO::FETCH_ASSOC);

甚至到目前为止你得到的最佳答案,

$result = $conn->prepare("SELECT * FROM status WHERE status_id = ?");
$result->execute([$id]);

更不用说后者并不总是可用,因为它只适合获取数组。使用真实的速记时,任何结果格式都是可能的:

$result = $conn->run($sql, [$id])->fetchAll(); // array
$result = $conn->run($sql, [$id])->fetch(); // single row
$result = $conn->run($sql, [$id])->fetchColumn(); // single value
$result = $conn->run($sql, [$id])->fetchAll(PDO::FETCH_*); // dozens of different formats

答案 1 :(得分:4)

$stmt_test->execute([$id])返回boolean值。这意味着

$result = $stmt_test->execute([$id])->fetchAll(PDO::FETCH_ASSOC);

无效。相反,你应该做

$stmt_test->execute([$id]);
$result = $stmt_test->fetchAll(PDO::FETCH_ASSOC);

答案 2 :(得分:1)

您获得的错误来自PDO的设计方式。 </script>不返回语句,但是表示成功的布尔值。因此,您想要的快捷方式是不可能的。

请参阅http://php.net/manual/en/pdostatement.execute.php

中的功能定义

另外,让我补充一点,forEach()经常(并非总是)是一种代码气味并占用相对较多的内存,因为它必须将所有行存储为PHP值。

答案 3 :(得分:0)

我相信PDO的execute()方法返回true或false。正如错误已经告诉您:fetchAll()期望一个对象。使用三行代码将是最短的方式。

另一种选择是使用像propel这样的ORM,它的工作非常顺畅,可以节省很多时间。

答案 4 :(得分:-1)

这可能是最短的例子。

$('.status-box')