目前,要使用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
,但由于错误发生,必须有一些东西在我的逻辑中有缺陷。我究竟做错了什么?此外,有没有人知道一个更好的速记方法来执行以前的查询?
答案 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')