【问题标题】:MySQL connection: globally or in object?MySQL连接:全局还是对象?
【发布时间】:2012-01-16 07:36:57
【问题描述】:

我有两个 PHP 类。一种是连接到数据库、构建查询、执行查询以及断开与数据库的连接。另一类是针对用户的:添加、更新、登录等。

我正在争论我是否应该全局连接到页面上的数据库并使用该连接(将数据库对象传递给用户对象的方法),或者我是否应该从 a 内部连接和断开与数据库的连接用户方法本身。

我看到的全局连接的优势是,一旦连接,我就可以使用该连接来执行多种方法。缺点是我7需要担心传递数据库对象。

在方法内连接的优点是它是完全透明的,但是可能会建立和断开 4 或 5 个连接,这可能会导致开销。

是否有使用任何一种的最佳实践,或者它真的取决于用户数量和服务器的规格,例如内存、cpu等。系统最多需要支持大约1000个用户,所以规模相当小。

任何反馈都将不胜感激。

-瑞恩

【问题讨论】:

  • 我强烈建议实例化一次,然后将连接注入到您的对象中。尝试谷歌搜索“PHP 依赖注入”。

标签: php mysql database class object


【解决方案1】:

创建一个按需创建连接并提供对连接对象的访问的函数:

function getDb()
{
    static $db;
    if (!$db) $db = ...;
    return $db;
}

将这种方法封装到类中称为Singleton

【讨论】:

  • 这个函数在哪里?在对象中还是全局中?
  • @Ryan S.:您可以只使用函数或创建静态方法
  • 像这样的函数我称之为陷阱。它们甚至比全局或静态类数据库变量更糟糕。
  • 我只是留下一个很大的警告标志,因为我已经在多个项目中看到这会导致问题。这就是为什么我需要警告它,否则我会忽略我的专业经验。我不是非黑即白的,所以我对全局甚至单个类实例相当松懈,但是该结构的特定功能可能会对维护应用程序造成很多伤害。就是这样,不是可以称为 xyz 的点,而是建议具体实现的点。例如,在玩游戏时,全局变量可以更轻松地访问接缝。
【解决方案2】:

在 PHP 中,最佳实践是采用全局方法。这主要是因为重复连接/断开 MySQL 服务器会导致性能显着下降。

事实上,尽管这看起来违反直觉,但大多数 PHP 专家(包括我自己)建议您完全避免使用 mysql_close(),除非有迫切的理由不这样做。这是因为无论如何,这在 PHP 的清理中都会自动处理,因此添加 mysql_close() 只会进一步降低性能。

【讨论】:

  • 全局方法在任何编程语言中都不是一个好的做法,因为它很难管理
  • 我不同意这个答案。正如@zerkms 指出的那样,全局方法不是一个好主意。只连接一次数据库是个好主意,但是有更好的方法可以做到这一点,不会弄乱全局命名空间并使测试变得不可能。使用单例模式是一种方法,尽管它也使测试变得困难。查看依赖注入或尝试类似 zerkms 的功能。
  • @rdlowrey:+1,但 DI 是一个复杂的解决方案,这意味着深厚的理论知识和经验,以及代码测试本身。所以我个人更喜欢单例作为良好设计的第一步;-)
  • @zerkms 你可能是对的......据说人们学习的第一个设计模式通常是单例。这是一个很好的起点。
  • @rdlowrey 我认为 Ryan 在使用“全局”一词时所指的不是将连接处理程序分配给全局变量(我同意这不是一个好主意!),而是只创建一次连接,然后根据需要传递该数据库对象,而无需每次都连接/断开与 MySQL 的连接。这就是我的回答专门针对的问题。 =)
【解决方案3】:

一定要跟踪并重用您的数据库基类中的单个连接。以上是根据需要从 DB 类创建和返回该连接的一个很好的示例。

为了使您的实际对象更容易访问该连接,您可以创建一个基对象类(称为 DBable 或其他东西),该类在其构造函数中调用 getDb 并将其分配给该类中的本地 $db 变量。然后,您所有需要访问数据库的对象都可以扩展该 DBable 类,并且始终有一个隐式可用的 $db 引用,而无需记住在任何地方都调用 getDb。

【讨论】:

  • 这不是一个坏主意,但 PHP 缺乏多重继承使得使用父类来实现此功能存在问题。在这种情况下,也许界面会更好?
  • 优先组合而不是继承。实体不是数据库。所以 - 不要继承它。
【解决方案4】:

我正在争论我是否应该全局连接到页面上的数据库并使用该连接(将数据库对象传递给用户对象的方法),或者我是否应该从 a 内部连接和断开与数据库的连接用户方法本身。

停止争论。使数据库类可供需要它的函数使用,并透明地处理连接,以便每个请求都有一个连接。进行多次连接/断开连接是多余的,只会创建太多不需要完成的工作。

所以实际上你只需要一个连接变量(对象)。使其可用于需要它的功能(例如,将其作为成员的数据库类),你很好。是否使该对象全局可用是您的设计决定。

另外查看名为table data gateway 和/或active record pattern 的模式。可能这就是您对用户对象所做的事情,因此您不需要重新发明轮子,您可以使用现有的库来代替,这样您就可以更好地专注于需要在应用程序中完成的实际工作。

【讨论】:

  • Make the database class available to the functions that need it --- php 中的类总是可用的,因为它们是在全局空间中声明的。你一定是在谈论database class instance, thus object,不是吗?
  • 取决于它是如何实现的,可能会因实现而异,所以一定不能对也不能错。
  • 问题是关于实施。您的回答对原始讨论没有任何帮助。 OP 知道他需要以某种方式实现它,但不知道如何实现。您的回答都没有解释这一点。
猜你喜欢
  • 2020-09-22
  • 1970-01-01
  • 1970-01-01
  • 2019-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多