当前位置: 首页 > 面试题库 >

在PHP中是否有用于数据库访问的单例的用例?

仇迪
2023-03-14
问题内容

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

我想到的第一件事是global

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

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

这被认为是不好的做法。稍作搜索后,我得到了Singleton模式,该模式

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

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

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();

为什么我需要这个相对较大的课程?

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了。

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


问题答案:

好的,当我刚开始我的职业生涯时,我想了一下。以不同的方式实现它,并提出了两个选择不使用静态类的理由,但它们是相当大的。

一种是,您会发现很多时候,您绝对可以确定自己永远不会有一个以上的实例,而最终又会有一个实例。您可能最终会得到第二个监视器,第二个数据库,第二个服务器(无论如何)。

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

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

这实际上归结为习惯-当人们说“全球”很糟糕时,他们有很好的理由这么说,但是在您亲自解决问题之前,它可能并不总是显而易见的。

您可以做的最好的事情是(像您一样)提出问题,然后做出选择并观察决定的后果。与一开始就正确地掌握代码相比,掌握随着时间的推移解释代码演变的知识更为重要。



 类似资料:
  • 问题内容: 我通过PDO访问我的MySQL数据库。我正在设置对数据库的访问权限,而我的第一个尝试是使用以下内容: 我想到的第一件事是: 这被认为是不好的做法。稍作搜索后,我得到了Singleton模式,该模式 “适用于需要一个类的单个实例的情况。” 根据手册中的示例,我们应该这样做: 为什么我需要这个相对较大的班级? 最后一个效果很好,我不必担心了。 如何创建较小的单例类,或者在PHP中缺少单例的

  • 问题内容: 为了进行快速测试,调试,创建可移植的示例和进行基准测试,R提供了许多数据集(在Base R包中)。R提示符下的命令描述了近100个历史数据集,每个数据集都有相关的描述和元数据。 Python有这样的东西吗? 问题答案: 您可以使用package从Python访问所有R数据集。 设置界面: 然后使用可用数据集的任何数据集名称进行调用(就像中的一样) 要查看可用数据集的列表以及每个数据集的

  • 问题内容: 在PHP中使用单例而不是全局的数据库连接有什么好处?我觉得使用单例而不是全局会使代码变得不必要地复杂。 全局编码 用Singleton编码 如果除了全局或单例之外,还有一种更好的初始化数据库连接的方法,请提及它并描述它比全局或单例具有的优势。 问题答案: 我知道这很旧,但是Dr8k的答案 几乎 就在那里。 当您考虑编写一段代码时,假设它会改变。这并不意味着您要假设它会在将来的某个时刻对

  • 过去,匿名用户(比如脚本)可以通过RESTAPI查询Jenkins的某些方面。例如,查找启动特定构建作业的用户的姓名,或其执行日期。然而,在过去几年中,安全模型发生了变化,这似乎使这一点变得更加困难,即使对于只读访问也是如此。 我在用詹金斯做广告认证。我需要提供对脚本的API访问,但我不想使用特定用户的个人API令牌(在脚本中硬编码),因为脚本可能由我的组织中的任何人运行,包括作为其他自动化的一部

  • 本文向大家介绍Rxjava2_Flowable_Sqlite_Android数据库访问实例,包括了Rxjava2_Flowable_Sqlite_Android数据库访问实例的使用技巧和注意事项,需要的朋友参考一下 一、使用Rxjava访问数据库的优点: 1.随意的线程控制,数据库操作在一个线程,返回数据处理在ui线程 2.随时订阅和取消订阅,而不必再使用回调函数 3.对读取的数据用rxjava进

  • ForkJoinTask明确指出“可细分任务也不应执行阻塞输入/输出”。它的主要目标是“计算纯函数或在纯孤立对象上操作的计算任务”。我的问题是:- 为什么设计ForkJoinTask来限制阻塞IO任务 在我的场景中,单个请求执行两种类型的工作,其中一种是加密,它将CPU核心在200毫秒内推到100%,第二种是很少的数据库调用。任何类型的静态分区,例如用于加密的6个线程和用于阻塞IO的2个线程,都不