在类中使用全局变量

在类中使用全局变量,第1张

在类中使用全局变量

解决此问题的正确方法是将数据库对象注入另一个类(依赖项注入):

$db = new DB_MySQL("localhost", "root", "", "test"); // connect to the databaseinclude_once("pagi.php");$pagination = new Paginator($db);$records = $pagination->get_records("SELECt the, fields, you, want, to retrieve FROM `table`");class Paginator{        protected $db;    // Might be better to use some generic db interface as typehint when available    public function __construct(DB_MySQL $db)    {        $this->db = $db;    }    public function get_records($q) {        $x = $this->db->query($q);        return $this->db->fetch($x);    }}

解决该问题的另一种方法是将数据库类的实例注入使用它的方法中:

$db = new DB_MySQL("localhost", "root", "", "test"); // connect to the databaseinclude_once("pagi.php");$pagination = new Paginator();$records = $pagination->get_records("SELECt the, fields, you, want, to retrieve FROM `table`", $db);class Paginator{    public function get_records($q, DB_MySQL $db) {        $x = $db->query($q);        return $db->fetch($x);    }}

您选择哪种方法取决于情况。如果只有一个方法需要数据库的实例,则可以将其注入该方法,否则我会将其注入到类的构造函数中。

另请注意,我已将您的班级从重命名

pagi
Paginator
。Paginator是该类的更好的名字恕我直言,因为其他人(重新)查看您的代码很明显。另请注意,我已将首字母大写。

我所做的另一件事是更改查询以选择要使用的字段,而不是使用“通配符”

*
。出于同样的原因,我也更改了类名:(重新)查看代码的人员将确切知道将检索哪些字段,而无需检查数据库和/或结果。

更新资料

因为答案引起了关于为什么我要走依赖注入途径而不是声明对象的讨论,所以我想

global
阐明为什么我要对
global
关键字使用依赖注入:当您有如下方法时:

function get_records($q) {    global $db;    $x = $db->query($q);    return $db->fetch($x);}

当您在某处使用上述方法时,不清楚使用的类或方法取决于

$db
。因此,这是一个隐藏的依赖关系。上面的代码不好的另一个原因是因为您已经将
$db
实例(因此
DB_MySQL
)类与该方法/类紧密耦合。如果您需要在某个时候使用2个数据库怎么办。现在,您将需要遍历所有代码才能更改
global$db
global $db2
。您永远不必为了切换到另一个数据库而更改代码。因此,您不应该这样做:

function get_records($q) {    $db = new DB_MySQL("localhost", "root", "", "test");    $x = $db->query($q);    return $db->fetch($x);}

同样,这是一个隐藏的依赖关系,并将

DB_MySQL
类与方法/类紧密耦合。因此,不可能正确地对
Paginator
类进行单元测试。
Paginator
您不仅要同时测试单元(课程),还要同时测试
DB_MySQL
课程。如果您有多个紧密耦合的依赖关系,该怎么办?现在,您突然用所谓的单元测试测试了几个类。因此,在使用依赖注入时,您可以轻松切换到另一个数据库类,甚至可以切换到一个模拟类来进行测试。除了只测试一个单元的好处(您不必担心由于依赖性而导致的错误结果)之外,它还可以确保测试能够快速完成。

某些人可能认为Singleton模式是访问数据库对象的正确方法,但是应该很清楚,在阅读了以上所有内容之后,Singleton基本上只是另一种制作方法

global
。它的外观可能有所不同,但具有与相同的特征,因此也存在相同的问题
global



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5588221.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存