【问题标题】:MySQLi class pattern for connection, close, leave open?MySQLi 用于连接、关闭、保持打开的类模式?
【发布时间】:2011-11-29 15:04:04
【问题描述】:

我想知道创建一个像下面这样的类是否是一种好习惯。

所以每次我需要做一些工作时我都会使用 self::$mysqli 对象,并且连接只会在 __desctruct() 上关闭。此外,由于 $mysqli 被声明为静态,因此扩展类仍将只维护一个连接。

这样我就只有一个连接认为脚本

class db {
 protected static $mysqli;

 function __contruct(){
  $this->mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_DATABASE);
  // DB_HOST, DB_USER, DB_PASS, DB_DATABASE defined elsewhere
 }

 function __destruct(){
  $this->mysqli->close();
 }
}

我想知道您对此的看法。

【问题讨论】:

    标签: php mysql mysqli connection


    【解决方案1】:

    我想知道创建一个像下面这样的类是否是一个好习惯。

    我认为这不是一个好习惯。这尤其是出于一个原因:您描述的问题是您认为需要它的原因:每个请求只有一个连接。

    您无需编写任何代码。 mysqli 有一个很好的内置功能,默认连接。每次创建新实例时,它都会从 ini 设置(配置)中选择数据库连接参数:

    $db = new mysqli;
    

    由于脚本完成后所有数据库连接都将关闭,因此根本不需要关心太多。您唯一需要做的就是将连接实例化一次并将变量传递给所有需要该mysqli 对象的代码。

    另一个不好的做法是你在这里引入Singleton Doc,类似于:

    class MysqliSingleton extends mysqli
    {
        private static $instance;
        /**
         * @return MysqliSingleton
         */
        public function getInstance()
        {
            if (NULL === self::$instance)
                self::$instance = new self();
            return self::$instance;
        }
        private function __construct()
        {
        }
        public function __clone()
        {
             throw new RuntimeException('Clone is not allowed.');
        }
        public function __wakeup()
        {
            throw new RuntimeException('Unserializing is not allowed.');
        }
    }
    

    它会像这样工作:

    $mysqli = MysqliSingleton::getInstance();
    

    并且总是会返回一个 mysqli 实例,这可能是您正在寻找的。然而,单身人士被认为是有害的,因为它们会带来很多问题,请参阅相关问题Who needs singletons?

    您自己创建一个包含数据库实例的变量会更容易。您还可以封装某种延迟加载,以防您的应用程序并不总是需要 mysqli 连接,例如有一个非常简单的上下文类:

    interface ContextMysqli
    {
        /**
         * @return mysqli
         */
        public function getMysqli();
    }
    
    class Context implements ContextMysqli
    {
        private $mysqli;
        public function getMysqli()
        {
            $this->mysqli || $this->mysqli = new mysqli();
            return $this->mysqli;
        }
    }
    

    当您的脚本启动时,只需实例化您的上下文并将其传递给您需要它的代码的每个部分:

    $context = new Context();
    ...
    $result = do_some_db_work($context);
    ...
    function do_some_db_work(ContextMysqli $context)
    {
        $mysqli = $context->getMysqli();
        ...
    }
    

    这个建议也可能有点短视,但它比单例要好,而且不会引入太多麻烦。好处是您已经封装了何时创建 mysqli 对象而无需单例的逻辑。您的代码现在独立于全局或静态上下文。

    【讨论】:

      【解决方案2】:

      当 PHP 完成执行后,它将自动关闭所有连接,因此无需显式关闭连接,除非优化相当大的系统或内存使用量必须保持在绝对最小值。

      您在上面的设置只会在连接打开时保持打开状态,您可以查看单例模式,但对于这个基本用例来说,这严重过度。

      话虽如此,最后关闭它并没有什么坏处:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-06
        • 2015-12-25
        • 1970-01-01
        相关资源
        最近更新 更多