PHP-最佳实践类中的全局数据库变量(OOP)


PHP - Best practice Global database variable in class (OOP)

当您有多个具有执行查询的方法的类时,访问数据库的"最佳实践"是什么?

全局$db变量:

$db = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
class Item {
    private $id;
    function __construct($id) {
        $this->id = $id;
    }
    public function remove() {
        global $db;
        // queries and stuff.
    }
}

或者,将$db传递给构造函数?

$db = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
$item = new Item(5,$db);
class Item {
    private $id;
    protected $db;
    function __construct($id,$db) {
        $this->id = $id;
        $this->id = $db;
    }
    public function remove() {
        // queries and stuff.
    }
}

或者也许另一种方式比这两者都好?

对于可以在任何地方使用的全局对象,我个人更喜欢单例类:

class DBConnection {
     private static $instance = null;
     private $db;
     private function __construct() {
         $this->db = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
     }
     public static function getDB() {
           if (self::$instance === null) { 
               self::$instance = new self();
           }
           return self::$instance->db;
     }    
}

通过这种方式,您可以在任何需要的地方调用:DBConnection::getDB(),这也可以用于自动加载。

构造函数注入是更好的方法。该类明确表示,它需要访问数据库。从长远来看,这将有助于维护应用程序。您可以使用依赖注入容器(DI或IOC)来自动填充所需的服务。有许多关于在PHP中使用Deendency注入的好博客文章。Symfony文档在解释优点方面做得很好。

全局参数在OOP中被认为是不好的做法,应该完全省略。

第三种可能性是使用singleton(不被认为是最佳实践)或像旧的Laravel版本一样使用静态外观。静态立面是一个热门话题。您可以在Laravel文档中找到更多关于它们的信息。