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

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

问题描述

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



我想到的第一件事是 global

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

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

这被认为是不好的做法。经过一番搜索之后,我最终获得了单身人士模式,其中


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


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

  class Database {
private static $ instance,$ db;

私有函数__construct(){}

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

return self:$ instance;
}

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

return self :: $ db;
}
}

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

some_function();

为什么我需要相对较大的类才可以这样做?

  class Database {
private static $ db;

私有函数__construct(){}

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

return self :: $ db;
}
}

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

some_function();

最后一个工作完美,我不需要担心 $ db



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

解决方案

好的,当我第一次开始职业生涯的时候,我想到了一段时间。实现不同的方式,并提出了选择不使用静态类的两个原因,但它们是相当大的。



其中一个是你会经常发现你绝对肯定你永远不会有一个以上的实例,你最终有一秒钟。您可能会得到第二个监视器,第二个数据库,第二个服务器 - 无论如何。



发生这种情况时,如果您使用静态类,对于一个更糟糕的重构,如果你使用单身人士。单例本身就是一个iffy模式,但它相当容易地转换成一个智能的工厂模式 - 甚至可以转换为使用依赖注入而没有太多的麻烦。例如,如果您的单例通过getInstance()获取,您可以很容易地将其更改为getInstance(databaseName)并允许多个数据库 - 无其他代码更改。



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



它真的归功于习惯 - 当人们说全球人是坏的时候,他们有很好的理由这样说,但直到你有自己遇到问题。



你可以做的最好的事情就是问(像你这样做),然后作出选择,并观察你的决定的后果。知道如何解释您的代码随着时间的演变比起首先要做的更重要。


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

The first thing I thought of is 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::$rand))
            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();

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

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.

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.

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天全站免登陆