php设计模式 Singleton(单例模式)

下面就让我来详细讲解一下 PHP 设计模式 Singleton(单例模式)的完整攻略。

什么是单例模式?

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并且提供了一个全局访问点来访问这个实例。单例模式通常用于管理共享资源,例如数据库连接、日志文件等等。

单例模式的使用场景

当一个类的实例化需要耗费很多资源的时候,或者介于全局变量和局部变量之间,适合使用单例模式。

单例模式的实现方法

饿汉式实现

饿汉式实现是指单例模式在类加载的时候就创建了实例,因此也叫做静态单例模式。这种方式实现简单,线程安全,但是可能会浪费一些资源,因为不一定每次都需要实例化这个对象。实现方法如下:

class Singleton
{
    private static $instance = new Singleton();

    private function __construct()
    {
    }

    public static function getInstance(): Singleton
    {
        return self::$instance;
    }
}

懒汉式实现

懒汉式实现是指单例模式只有在第一次使用的时候才创建实例。这种实现方式避免了内存浪费的问题,但是需要考虑线程安全性问题。实现方法如下:

class Singleton
{
    private static $instance;

    private function __construct()
    {
    }

    public static function getInstance(): Singleton
    {
        if (!isset(self::$instance)) {
            self::$instance = new Singleton();
        }
        return self::$instance;
    }
}

这种方式有一个线程安全问题,可能会出现同时创建两个实例的情况。可以在 getInstance 方法上加锁来解决。

class Singleton
{
    private static $instance;

    private function __construct()
    {
    }

    public static function getInstance(): Singleton
    {
        if (!isset(self::$instance)) {
            self::$instance = new Singleton();
        }
        return self::$instance;
    }

    public static function getInstanceThreadSafe(): Singleton
    {
        static $instance;
        if (!isset($instance)) {
            self::$instance = new Singleton();
        }
        return $instance;
    }
}

单例模式的示例代码

下面给出两个单例模式的示例代码。

示例代码一:日志类

在例子中,我们模拟了一个日志类。日志类通过单例模式实现了只有一个实例,可以全局调用。

class Log
{
    private static $instance;
    private $logs = [];

    private function __construct()
    {
    }

    public static function getInstance(): Log
    {
        if (!isset(self::$instance)) {
            self::$instance = new Log();
        }
        return self::$instance;
    }

    public function add($log)
    {
        $this->logs[] = $log;
    }

    public function printLogs()
    {
        foreach ($this->logs as $log) {
            echo $log . "\n";
        }
    }
}

// example usage
$log = Log::getInstance();
$log->add('log 1');
$log->add('log 2');
$log->add('log 3');
$log->printLogs();

示例代码解析:

  1. Log 类是一个单例类,它只需要在第一次使用的时候实例化,所以我们在 getInstance 方法中实现单例模式。
  2. add 方法用于添加一条日志,printLogs 方法用于打印所有的日志。

示例代码二:数据库连接类

在例子中,我们模拟了一个数据库连接类。数据库连接类通过单例模式实现了保证只有一个数据库连接实例。

class Database
{
    private static $instance;
    private $db;

    private function __construct()
    {
        $this->db = new PDO('mysql:host=localhost;dbname=test', 'root', 'password');
    }

    public static function getInstance(): Database
    {
        if (!isset(self::$instance)) {
            self::$instance = new Database();
        }

        return self::$instance;
    }

    public function query($sql)
    {
        return $this->db->query($sql);
    }
}

// example usage
$db = Database::getInstance();
$result = $db->query('SELECT * FROM users');
foreach ($result as $row) {
    echo $row['id'] . ':' . $row['name'] . "\n";
}

示例代码解析:

  1. Database 类是一个单例类,它只需要在第一次使用的时候实例化,所以我们在 getInstance 方法中实现单例模式。
  2. query 方法用于执行 SQL 查询,返回的是 PDOStatement 对象。

以上就是单例模式的完整攻略。单例模式在实际开发中非常常见,可以想象在一个应用程序中,可能需要访问的资源非常多,而我们不希望每次都去创建全新的实例,而是希望尽可能的减少资源的消耗。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:php设计模式 Singleton(单例模式) - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • PHP对接阿里云虚拟号的实现(号码隐私保护)

    下面是详细讲解“PHP对接阿里云虚拟号的实现(号码隐私保护)”的完整攻略。 1. 准备工作 首先,需要在阿里云控制台创建云通信号码池,获取到以下参数:- AccessKeyID: 阿里云账号的Access Key ID- AccessKeySecret: 阿里云账号的Access Key Secret- Endpoint: 阿里云API服务的Endpoint…

    PHP 2023年5月23日
    00
  • PHP之sprintf函数用法详解

    PHP之sprintf函数用法详解 简介 sprintf函数是PHP语言中一个强大的格式化输出函数。它可以用于将一个字符串格式化输出为你所需要的样式并返回这个字符串。 基本语法 sprintf函数的基本语法如下: sprintf(string $format, mixed $args, …): string; 其中,$format参数为格式化字符串,$a…

    PHP 2023年5月26日
    00
  • PHP登录验证码的实现与使用方法

    下面是详细的讲解“PHP登录验证码的实现与使用方法”的完整攻略。 简介 验证码是一种保证用户身份的有效方法。当用户注册或登录时,他们必须输入一个验证码,以验证他们确实是人类而不是机器自动化程序。这可以防止恶意程序在网站上进行刷屏、自动注册或垃圾邮件。 PHP是一种广泛使用的后端编程语言。PHP登录验证码可以很容易地与PHP结合使用以提高网站安全性。 实现方法…

    PHP 2023年5月26日
    00
  • PHP中比较两个字符串找出第一个不同字符位置例子

    要比较两个字符串在哪里出现第一个不同字符,可以使用PHP预定义函数 strcmp() 。 strcmp() 函数用于比较两个字符串,字符串可以是变量或者常量,返回值不同表示找到的第一个不同字符的位置也不同。如果相等,则返回 0。 下面是一个使用 strcmp() 比较两个字符串并查找第一个不同字符位置的例子: $str1 = "Hello Worl…

    PHP 2023年5月26日
    00
  • PHP eval函数使用介绍

    PHP eval函数使用介绍 什么是eval函数 eval 函数是 PHP 的内置函数之一,它有一个参数,表示需要执行的 PHP 代码字符串。eval 函数的作用是执行一个字符串代码,并将其结果返回。如果字符串不是有效的 PHP 代码,那么 eval 函数将会抛出一个 Parse Error 异常。 eval函数的用法 eval 函数的基本语法格式如下: e…

    PHP 2023年5月25日
    00
  • destoon切换城市后实现logo旁边显示地区名称的方法

    下面是详细的“destoon切换城市后实现logo旁边显示地区名称的方法”的攻略: 步骤一:获取当前城市名称 在切换城市的过程中,先要获取当前城市的名称,可以通过以下两种方式实现: 方式一:使用HTML5的Geolocation API Geolocation API是HTML5新加入的API,通过这个API,可以获取到用户当前的地理位置。代码如下: if …

    PHP 2023年5月23日
    00
  • php获取当前月与上个月月初及月末时间戳的方法

    获取当前月的月初和月末时间戳的方法 获取当前月份的月初和月末时间戳是比较常用的操作,可以通过PHP中的日期函数快速实现。以下是获取当前月份的月初和月末时间戳的示例代码: // 获取当前月份的月初和月末时间戳 $firstDay = strtotime(date(‘Y-m-01’)); // 当前月份第一天的时间戳 $lastDay = strtotime(d…

    PHP 2023年5月26日
    00
  • php使用数组填充下拉列表框的方法

    下面我将为您详细讲解“php使用数组填充下拉列表框的方法”的完整攻略。 一、准备工作 首先,我们需要在html文件中定义一个下拉列表框,代码如下: <select name="fruit"> </select> 这里的“fruit”为下拉列表框的名称,可以根据自己的需求进行修改。 二、数组填充下拉列表框方法一 方法…

    PHP 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部