当您有多个具有执行查询的方法的类时,访问数据库的"最佳实践"是什么?
全局$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文档中找到更多关于它们的信息。