【问题标题】:Where to put PDO prepared statements in a DB_Connector class - in the constructor or the functions?将 PDO 准备好的语句放在 DB_Connector 类中的什么位置 - 在构造函数或函数中?
【发布时间】:2020-10-14 13:54:12
【问题描述】:

我的 Web 项目有一个名为 DB_CONNECTOR 的类,其中捆绑了与 mysql 数据库交互的所有函数。这些函数包括get_user()add_user()change_user_attribute() 等等。在这些函数中的每一个函数中都会执行一个 sql 查询,作为一种好的做法,我使用准备好的语句(带有命名参数)。

目前与数据库的连接是在类的构造函数中建立的,并且所有语句都在那里准备好。我认为这是个好主意,所以这些语句都可以立即执行。

现在我意识到我的用例通常是创建一个 db_connector 对象,执行一个或两个函数,然后对象生命周期结束,并且在稍后的步骤中可能会构造(或不构造)新的对象。所以,我不太确定将准备好的语句放在构造函数中是否明智,因为可以预见我最终会得到至少 20 个或更多的准备好的语句。

所以我的问题是:

  • 即使只使用一两个语句,在构造函数中准备所有语句是否是个好主意?
  • 或者我应该在执行前在函数中准备它们以避免不必要的准备工作给数据库带来压力?

【问题讨论】:

  • 我想你在这里真的回答了你自己的问题:)

标签: php mysql pdo prepared-statement


【解决方案1】:

这个答案基于我的经验和拙见,但我会尝试详细阐述我的论点,以免它只是一些随机的人的意见。

我认为数据库连接不一定是您应用程序中的核心对象,更不用说唯一了。它希望为用户看到一个完全不同的类,因此您以后可以为其他所有内容提供更多类。否则,您的应用程序最终将包含 5000 行文件中的单个类,并且您的类将不适合在实例级别跟踪实体数据,并且您需要在方法调用中传递变量。这几乎是 OOP 服装中的程序代码。

另外,我不认为让你的 User 类继承自 Database (尽管如此,这很常见)是切合实际的。将数据库连接和业务逻辑对象交错并不能真正简化应用程序设计,实际上会使某些部分变得更加困难。

数据库层本身的设计非常标准化:

  • 每个应用程序一个连接(或更多...您可能需要连接到多个源!)
  • 每个查询一个语句。

这正是 PDO 的工作原理。

鉴于此,使数据库类成为实体的一种依赖项而不是它们的祖父项更容易。这种依赖的注入可以通过不同的方式来完成:

  • 使其成为类属性:

    public function __construct(\PDO $connection)
    {
        $this->connection = $connection;
    }
    
  • 将它传递给他们实际需要的方法(如果不是很多):

    public function getOrders(\PDO $connection)
    {
        $stmt = $connection->prepare('SELECT ...');
    }
    
  • ...或者使用您可以在 Packagist 找到的那些花哨的依赖注入容器之一。

请注意,还有 object-relational mapping (ORM)、active record pattern... 这些是完全不同的解决方案系列,可能适合您的需求,也可能不取决于您的用例,但不是我所描述的在这里。


也就是说,很明显,您在需要它们的确切位置准备语句。这种设计甚至不允许其他情况;-)

【讨论】:

  • 谢谢!我想在我完全理解之前,我必须再读几次你的答案(这对这一切仍然很陌生)。但我从中得到的是:短期将它们转移到函数中。按照您的建议,长期消除对专用 db_connector 类的需求。
猜你喜欢
  • 2014-07-20
  • 2011-05-14
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多