是否有使用 PHP 访问数据库的单身人士的用例? [英] Is there a use-case for singletons with database access in PHP?

查看:18
本文介绍了是否有使用 PHP 访问数据库的单身人士的用例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过 PDO 访问我的 MySQL 数据库.我正在设置对数据库的访问,我的第一次尝试是使用以下内容:

I access my MySQL database via PDO. I'm setting up access to the database, and my first attempt was to use the following:

我首先想到的是global:

$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'root', 'pwd');

function some_function() {
    global $db;
    $db->query('...');
}

这被认为是一种不好的做法.经过一番搜索,我最终得到了单例模式,其中

This is considered a bad practice. After a little search, I ended up with the Singleton pattern, which

适用于需要一个类的单个实例的情况."

"applies to situations in which there needs to be a single instance of a class."

根据手册中的例子,我们应该这样做:

According to the example in the manual, we should do this:

class Database {
    private static $instance, $db;

    private function __construct(){}

    static function singleton() {
        if(!isset(self::$instance))
            self::$instance = new __CLASS__;

        return self:$instance;
    }

    function get() {
        if(!isset(self::$db))
            self::$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'user', 'pwd')

        return self::$db;
    }
}

function some_function() {
    $db = Database::singleton();
    $db->get()->query('...');
}

some_function();

当我可以这样做时,为什么我需要那个相对较大的类?

Why do I need that relatively large class when I can do this?

class Database {
    private static $db;

    private function __construct(){}

    static function get() {
        if(!isset(self::$db))
            self::$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'user', 'pwd');

        return self::$db;
    }
}

function some_function() {
    Database::get()->query('...');
}

some_function();

最后一个工作得很好,我不再需要担心 $db.

This last one works perfectly and I don't need to worry about $db anymore.

如何创建一个较小的单例类,或者是否有我在 PHP 中缺少的单例用例?

How can I create a smaller singleton class, or is there a use-case for singletons that I'm missing in PHP?

推荐答案

好的,当我第一次开始我的职业生涯时,我想过一段时间.以不同的方式实现它并提出了两个选择不使用静态类的原因,但它们非常重要.

Okay, I wondered over that one for a while when I first started my career. Implemented it different ways and came up with two reasons to choose not to use static classes, but they are pretty big ones.

一个是你会发现很多时候你绝对确定你永远不会有超过一个实例的东西,你最终会有第二个.您最终可能会得到第二个监视器、第二个数据库、第二个服务器——随便什么.

One is that you will find that very often something that you are absolutely sure that you'll never have more than one instance of, you eventually have a second. You may end up with a second monitor, a second database, a second server--whatever.

发生这种情况时,如果您使用了静态类,那么与使用单例相比,您将面临更糟糕的重构.单例模式本身就是一个不确定的模式,但它可以很容易地转换为智能工厂模式——甚至可以转换为使用依赖注入而不会有太多麻烦.例如,如果您的单例是通过 getInstance() 获得的,您可以很容易地将其更改为 getInstance(databaseName) 并允许使用多个数据库——无需更改其他代码.

When this happens, if you have used a static class you're in for a much worse refactor than if you had used a singleton. A singleton is an iffy pattern in itself, but it converts fairly easily to an intelligent factory pattern--can even be converted to use dependency injection without too much trouble. For instance, if your singleton is gotten through getInstance(), you can pretty easily change that to getInstance(databaseName) and allow for multiple databases--no other code changes.

第二个问题是测试(老实说,这与第一个问题相同).有时您想用模拟数据库替换您的数据库.实际上,这是数据库对象的第二个实例.静态类比单例更难做到这一点,您只需要模拟 getInstance() 方法,而不是静态类中的每个方法(这在某些语言中可能非常困难).

The second issue is testing (And honestly, this is the same as the first issue). Sometimes you want to replace your database with a mock database. In effect this is a second instance of the database object. This is much harder to do with static classes than it is with a singleton, you only have to mock out the getInstance() method, not every single method in a static class (which in some languages can be very difficult).

这真的归结为习惯——当人们说全球性"不好时,他们有很好的理由这么说,但在您自己解决问题之前,这可能并不总是显而易见的.

It really comes down to habits--and when people say "Globals" are bad, they have very good reasons to say so, but it may not always be obvious until you've hit the problem yourself.

您能做的最好的事情是询问(就像您所做的那样)然后做出选择并观察您的决定的后果.拥有解释代码随时间演变的知识比一开始就正确执行要重要得多.

The best thing you can do is ask (like you did) then make a choice and observe the ramifications of your decision. Having the knowledge to interpret your code's evolution over time is much more important than doing it right in the first place.

这篇关于是否有使用 PHP 访问数据库的单身人士的用例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆