【问题标题】:Using db connection everywhere inside PHP application在 PHP 应用程序中随处使用 db 连接
【发布时间】:2012-03-29 22:47:42
【问题描述】:

我有一个看起来像这样的 db 类

class db {

    protected $db;

    public function __construct() {
        $this->connect();
    }

    protected function connect() {
        $this->db = new MySQLi(db_host, db_user, db_pass, db_name) or die($this->db->error);
        $this->db->set_charset('utf8');
    }

}

我的 PHP 应用程序中的每个类都扩展了这个 db 类

喜欢

class registration extends db {

    var $validation;

    function __construct() {
        parent::__construct();
        $this->validation = new validation();
...

验证看起来像这样

class validation extends db {

    var $ajax, $common;

    function __construct() {
        parent::__construct();
...

收到错误消息“连接过多”。我觉得,这不是正确的方法:我每次都重新连接到 db。那么你认为正确的方法是什么?是否可以定义('db', ...) 1 次并在应用程序内的任何地方使用?

【问题讨论】:

    标签: php database class mysqli


    【解决方案1】:

    registrationvalidation使用 db 的类,但不是它的子类。

    您的代码应如下所示:

    $db = new DB();
    $db->connect();
    $registration = new Registration($db);
    
    class Registration {
    
        private $db;
    
        public function __construct(DB $db) {
            $this->db = $db;
            ...
    

    您将对$db 实例的引用传递给所有需要它的类。

    您打开太多连接的原因可能是因为当前每个类都与您的数据库建立了自己的连接,而这不是您想要做或需要做的。

    【讨论】:

    • @epic_syntax,是的,你也可以在这里定义连接。此解决方案与我的解决方案相同,只是您将 db 类的实例传递给所有其他类,因为它们在应用程序中被实例化,而使用 Singleton 每个类都可以获得类本身的实例,这将发生在到处都是相同的实例。如果您不熟悉设计模式,这可能是一个更容易理解的解决方案,但我仍然鼓励您探索 Singleton;数据库连接是它的一个常见用例。
    【解决方案2】:

    您想在此处使用合成。也可以考虑研究单例模式。

    详细说明,使用组合,您的库中的每个类都将拥有一个 db 类的实例,而不是成为一个 db 类的实例。

    Singleton 将使 db 类强制只创建该类的一个实例,这对于数据库连接等共享资源很有用。请查看此链接以进一步阅读该主题。

    http://php.net/manual/en/language.oop5.patterns.php

    编辑:添加一些代码

    将 db 类变成单例

    <?php
    class db
    {
        static private $_oInstance = null;
        protected $db;
    
        private function __construct()
        {
            $this->connect();
        }
    
        static public function getInstance()
        {
            if(self::$_oInstance === null)
                self::$_oInstance = new db();
            return self::$_oInstance();
        }
    
        protected function connect()
        {
            $this->db = new MySQLi(db_host, db_user, db_pass, db_name) or die($this->db->error);
            $this->db->set_charset('utf8');
        }
    
    }
    

    修改其余的类以组成 db 实例,而不是扩展 db 类

    class registration
    {
        private $_oDb;
        public $validation;
    
        function __construct()
        {
            parent::__construct();
            $this->_oDb = db::getInstance();
            $this->validation = new validation();
        }
    
        // ...
    }
    

    【讨论】:

    • 是的,db 类与当前的设计基本没有变化。您只是在更改它与应用程序中其余代码的关联方式。
    • 这种方法的一个“问题”是 any 类可以访问数据库资源。您无法连接到第二个数据库。而且你不能让你的代码使用db 的子类。依赖注入通常被认为是一种优越的范例,尤其是在模块化、维护和测试方面。
    • DI 也更复杂,每个类都需要更多样板代码。通过参数化构造函数(可能添加数组)应该很容易支持带单例的多个数据库连接。 DI 是我在实践中发现的经常被过度使用的东西,Singleton 在大多数情况下更实用。在使用设计模式时,应该小心选择最适合应用程序需求的抽象级别。设计模式的一个实际挑战是为正确的工作选择正确的工具。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 2017-06-15
    • 2017-03-27
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 2019-03-25
    相关资源
    最近更新 更多