【问题标题】:Single instance of a MySQL database connection via PHP Class通过 PHP 类的 MySQL 数据库连接的单个实例
【发布时间】:2015-10-16 02:45:53
【问题描述】:

我有以下数据库类。我的想法是,这将检查该类的现有实例并返回它,而不是创建一个新的数据库连接。

当我运行代码时,它会创建一个连接。当我刷新页面时,会创建另一个连接(检查 MySQL 连接)。

我的想法不正确吗?对使用 OOP 还很陌生,对于新手问题,我们深表歉意!

任何正确方向的帮助或指示将不胜感激。

非常感谢。

<?php
class Db
{
    private $_connection;
    private static $_instance; 
    private $_host = 'localhost';
    private $_username = 'root';
    private $_password = 'password';
    private $_database = 'test';

    public static function getInstance()
    {
        if (!self::$_instance) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    private function __construct()
    {
        try {
            $this->_connection  = new PDO("mysql:host=$this->_host;dbname=$this->_database", $this->_username, $this->_password); 
            echo 'Connected to database';
        } catch (PDOException $e) {
            echo $e->getMessage();
        }
    }

    private function __clone()
    {
    }

    public function getConnection()
    {
    return $this->_connection;
    }
}

$db = Db::getInstance();

【问题讨论】:

    标签: php mysql oop


    【解决方案1】:

    PHP 是一个“shared nothing”环境。 PHP 应用程序处理的每个请求都与所有其他请求隔离,可以作为单独的线程或单独的进程,具体取决于所使用的server api (SAPI)。您设计的类是singleton,但它与单个请求-响应周期隔离。这意味着,如果您在单个请求期间调用 Db::getInstance() 10 次,您将获得对同一对象的 10 次引用,但在单独请求中的单个调用将创建并返回一个不同的对象。

    您可以在服务器端或应用程序端使用某种类型的连接池来减少与后端数据库服务器建立的并发连接数。 PHP 的PDO 抽象通过PDO::ATTR_PERSISTENT 连接驱动程序选项启用应用程序端连接池。这些池连接被缓存在 PHP 父进程中,而不是处理请求并随后被重用的工作线程/进程中。根据您的 SAPI 和底层数据库类型,将打开的连接的确切数量以及它们的共享方式是可变的。

    【讨论】:

      【解决方案2】:

      在使用 PHP 作为服务器端语言时,了解后台发生的事情可能是一件好事。

      当您运行该代码时,PHP 会为您启动连接。它不会在页面加载后保持连接。

      在每个页面加载时都会打开新连接,以便您继续提出请求并执行任务。

      考虑一下如果这样做会发生什么。您关闭页面并进入睡眠状态,服务器将永远保持与数据库的开放连接。您获得了一些访问者,然后您达到了连接限制并收到 too many connections 错误。

      可能有一些引用可以引用,但我真的找不到很多,因为这更像是一个逻辑问题而不是编码问题。

      【讨论】:

        【解决方案3】:

        每次刷新页面时,都会实例化一个全新的 Db 对象,并将其分配给一个名为 $db 的全新变量,因此每次都会获得连接。我还认为您可能使您的 Db 类过于复杂。

        当我创建 db 类来包装 PDO 或 mysqli 时,想法是创建一个 db 对象,在实例化时将包含一个数据库连接作为它的属性之一。为了做到这一点,我会稍微改写你的课程。像这样的东西将是您创建具有私有连接的 Db 对象所需的全部内容,该连接可以被您希望添加到类中的任何其他方法使用...比如说,发出查询的方法,

        class Db
        {
            private $_connection;
            private $_host = 'localhost';
            private $_username = 'root';
            private $_password = 'flindersbeast';
            private $_database = 'flinders';
        
            public function __construct()
            {
                try {
                    $this->_connection = new PDO("mysql:host=$this->_host;dbname=$this->_database", $this->_username, $this->_password); 
                    echo 'Connected to database';
                } catch (PDOException $e) {
                    echo $e->getMessage();
                }
            }
        
            // Other methods here will use $this->_connection to do a variety of things.
            public function example()
            {
             // Do stuff - as needed you can pass $this->_connection to PDO 
            }
        }
        
        $db = new Db;
        

        祝你好运!

        【讨论】:

          猜你喜欢
          • 2010-10-23
          • 2013-08-06
          • 1970-01-01
          • 1970-01-01
          • 2014-07-31
          • 2012-12-29
          • 1970-01-01
          • 2014-12-19
          • 2018-12-19
          相关资源
          最近更新 更多