【问题标题】:PHP OOP Efficient DB Read ReductionPHP OOP 高效的数据库读取减少
【发布时间】:2025-12-08 12:50:01
【问题描述】:

六年前,我在没有任何经验的情况下开始了一个新的 PHP OOP 项目,所以我只是边做边编。无论如何,我注意到我相当强大的 mySQL 服务器有时太容易陷入困境,并且想知道限制某些 db 活动的最佳方法是什么,当我想出这个时,例如......

private $q_enghours;
public function gEngHours() {
    if ( isset($this->q_enghours) ) {
    } else {
        $q = "SELECT q_eh FROM " . quQUOTES . " WHERE id = " . $this->id;
        if ($r = $this->_dblink->query($q)) {
            $row = $r->fetch_row();
            $r->free();
            $this->q_enghours = $row[0];
        }
        else {
            $this->q_enghours = 0;
        }
    }
    return $this->q_enghours;
}

这似乎可以有效地大大减少对 db 的必要读取。如果填充了对象属性,则无需访问 db。请注意,几乎有两打类都具有相同的“getter”db 访问例程。我只在一个地方实现了这个更改,并且想知道在我重新编写所有类之前是否有可能错过的“最佳实践”。

【问题讨论】:

  • 让我们从您的代码对 SQL 注入 100% 开放的事实开始(绑定您的变量,不要将它们粘贴到 SQL 中!)。
  • 虽然是一个有效的观点,但这并不真正适用于我提出的问题。我在应用程序的不同部分处理了 SQL 注入。

标签: php oop methods mysqli


【解决方案1】:

我会说这个问题是基于错误的前提。

如果你想处理“容易陷入困境”的数据库,那么你必须挖掘特殊原因,而不是仅仅猜测。这些你如此关心的琐碎读物,实际上不会有任何影响。您必须剖析整个应用程序并找到真正的原因。

如果您想减少读取次数,则通过在对象创建时读取该记录并一次填充所有属性,使您的对象映射特定数据库记录。构造函数是为此而生的。

顺便说一句,您确实需要一个好的数据库包装器,只是为了减少每次数据库调用必须编写的代码量,所以,这段代码可以写成

public function gEngHours() {
    if ( !isset($this->q_enghours) ) {
        $this->q_enghours = $this->db->getOne("SELECT q_eh FROM ?n WHERE id = ?", quQUOTES,  $this->id);
    }
    return $this->q_enghours;
}

getOne() 方法完成了运行查询、获取行、从中获取第一个结果以及许多其他工作,例如正确的错误处理和确保查询安全。

【讨论】:

  • 我不是 DBA,所以我没有必要的知识来深入了解 mySQL 日志并找出我的根本原因在哪里。我已经调整了每一个我能找到好的信息的参数。至于 db 包装器,我仍然会完全重写......只是为了消除已经编写的代码。
  • 而且,是的,有几个地方我可以一次获取整个对象,但对于我只需要有关对象的特定信息的地方,我使用这些类。