php单例模式怎么正确使用

PHP单例模式是一种设计模式,它确保整个应用中某个类只有一个对象实例。在PHP中,可以使用三种方式实现单例模式:懒汉式单例、饿汉式单例和登记式单例。懒汉式单例是在第一次调用时实例化对象,而饿汉式单例是在类加载时就实例化对象。登记式单例是通过在配置文件中保存一个唯一的实例标识来实现的 。

单例模式简介

单例模式是一种设计模式,它保证一个类仅有一个实例,并提供一个全局访问点,在PHP中,我们可以通过以下几种方式实现单例模式:

1、懒汉式(线程安全)

php单例模式怎么正确使用

2、饿汉式

3、双重检查锁定(DCL)

4、静态内部类

php单例模式怎么正确使用

懒汉式(线程安全)

懒汉式单例模式是在第一次请求时实例化对象,这种方式简单易懂,但可能会导致线程安全问题,下面是一个简单的懒汉式单例模式实现:

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

饿汉式

饿汉式单例模式是在程序启动时就实例化对象,这样可以避免多线程环境下的线程安全问题,由于对象在程序启动时就已经创建,可能导致资源浪费,下面是一个简单的饿汉式单例模式实现:

class Singleton
{
    private static $instance = new self();
    private function __construct() {}
    public static function getInstance()
    {
        return self::$instance;
    }
}

双重检查锁定(DCL)

双重检查锁定是一种线程安全的单例模式实现方式,它在懒汉式的基础上增加了一层检查锁定机制,确保只有一个实例被创建,下面是一个简单的双重检查锁定单例模式实现:

php单例模式怎么正确使用

class Singleton
{
    private static $instance = null;
    private static $lock = false;
    private function __construct() {}
    public static function getInstance()
    {
        if (!self::$lock && null === self::$instance) {
            self::$lock = true;
            self::$instance = new self();
        } elseif (self::$lock && null !== self::$instance) {
            self::$instance->__clone(); // 防止克隆导致的内存泄漏问题
        } elseif (null !== self::$instance) { // 防止多个非线程安全的getInstance()调用同时执行到这一句,导致实例重复创建或未创建的情况发生,注意这里不能使用++操作符,因为它不是原子操作,这个判断条件要放在最前面,否则在多线程环境下可能会出现问题,具体请参考下面的示例代码,为了防止循环引用导致内存泄漏,可以使用SplObjectStorage来存储已经创建的实例,下面是一个简单的双重检查锁定单例模式实现:

class SplSingleton implements \IteratorAggregate, \ArrayAccess, \Countable, Serializable{//接口定义就不写了,具体可自行查阅相关资料,这里需要注意的是,如果要让SplSingleton支持序列化和反序列化操作,那么需要重载Serializable接口的serialize()和unserialize()方法,由于实现了IteratorAggregate、ArrayAccess、Countable三个接口,所以也可以使用foreach、offsetExists、count等数组相关的函数,最后是iterator(),这个函数返回一个迭代器对象,用于遍历SplSingleton中的元素,下面是一个简单的双重检查锁定单例模式实现:function __construct(){//构造函数私有化,防止外部直接创建实例,if(null===$this->instance){//加锁判断是否已经创建过实例if(!static::$lock){//加锁static::$lock=true;//加锁操作try{//加锁执行创建实例的操作$this->instance=new static();}finally{//无论是否成功都释放锁static::$lock=false;}}}}else{//如果已经存在实例,则克隆一份新的实例给当前实例$this->instance=$this->instance->__clone();}}public function __clone(){//禁止克隆function __clone(){throw new \Exception('不允许克隆');}}public function rewind(){//重置指针function rewind(){throw new \Exception('不允许重置指针');}}public function current(){//获取当前元素function current(){return $this->instance;}}public function key(){//获取键名function key(){return null;}}public function next(){//获取下一个元素function next(){throw new \Exception('不允许获取下一个元素');}}public function valid(){//判断是否还有下一个元素function valid(){return true;}}public function getIterator(){//返回迭代器对象return new ArrayIterator([$this->instance]);}}?>```

原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/260371.html

Like (0)
Donate 微信扫一扫 微信扫一扫
K-seo的头像K-seoSEO优化员
Previous 2024-01-25 06:54
Next 2024-01-25 06:56

相关推荐

  • php中static关键字的作用

    PHP中的static关键字用于在类中创建静态变量。静态变量在类的所有实例之间共享,而不是为每个实例单独存储。这使得可以在不创建对象的情况下访问静态变量。

    2024-01-19
    0119
  • 有效的Java集合框架 — 最佳实践和技巧

    Java集合框架是Java编程语言中的一个重要组成部分,它提供了一套经过验证的、高度可靠的类和接口,用于表示和操作数据结构,Java集合框架的主要目标是提供一种有效的方式来存储和操作数据,同时保持代码的简洁性和可读性,本文将介绍一些关于Java集合框架的最佳实践和技巧,帮助你更好地使用这个强大的工具。1、选择合适的集合类型Java集合……

    2023-12-16
    0129
  • C语言中static的用法有哪些

    C语言中的static关键字有很多用法,下面我们将详细介绍,1、1 定义在函数内部定义的变量称为局部变量,当函数调用结束后,局部变量会被销毁,而在函数外部定义的变量称为全局变量,全局变量的作用域是整个程序,如果需要在函数内部使用一个与外部作用域相关的变量,可以使用static关键字将其定义为静态局部变量,extern void static_func(); // 在其他源文件中声明静态函数,但

    2023-12-15
    0138
  • beginthread _

    beginthread _是一个Windows API函数,用于创建一个新的线程。它需要传递一个指向线程函数的指针和传递给线程函数的参数。

    2024-06-07
    0125
  • Android中ContentProvider组件详解

    什么是ContentProvider?ContentProvider是Android系统中的一个核心组件,它主要用于在不同应用程序之间共享数据,简单来说,ContentProvider就是一个数据共享的桥梁,它可以让一个应用程序访问另一个应用程序的数据,实现数据的互通。ContentProvider的主要功能1、数据存储:Conten……

    2024-01-19
    0213
  • java集合的使用场景有哪些方法

    Java集合是Java编程语言中用于存储和操作一组对象的类和接口,它们提供了一种高效的方式来管理和处理数据,使得程序员可以更加方便地进行数据的添加、删除、查找等操作,Java集合框架主要包括两种类型的容器:一种是集合(Collection),用于存储一组不唯一的对象;另一种是图(Map),用于存储具有映射关系的对象。Java集合的使用……

    2024-01-04
    0117

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

免备案 高防CDN 无视CC/DDOS攻击 限时秒杀,10元即可体验  (专业解决各类攻击)>>点击进入