0

0

一起聊聊PHP中的单例模式

青灯夜游

青灯夜游

发布时间:2021-07-26 19:05:24

|

4401人浏览过

|

来源于掘金--硬核项目经理

转载

在之前的文章《深入浅析php中的模板方法模式》中我们介绍了php中的模板方法模式,下面本篇文章带大家了解一下php设计模式中的单例模式。

一起聊聊PHP中的单例模式

单例模式绝对是在常用以及面试常问设计模式中排名首位的。一方面它够简单,三言两语就能说明白。另一方面,它又够复杂,它的实现不仅仅只有一种形式,而且在Java等异步语言中还要考虑多线程加锁的问题。所以在面试时,千万不要以为面试官出单例模式的问题就放松了,这个模式真的是可深可浅,也极其能体现一个开发者的水平。因为只要工作过一段时间,不可避免的就会接触到这个模式。

Gof类图及解释

GoF定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

GoF类图

立即学习PHP免费学习笔记(深入)”;

1.png

代码实现

class Singleton
{
    private static $uniqueInstance;
    private $singletonData = '单例类内部数据';

    private function __construct()
    {
        // 构造方法私有化,外部不能直接实例化这个类
    }

    public static function GetInstance()
    {
        if (self::$uniqueInstance == null) {
            self::$uniqueInstance = new Singleton();
        }
        return self::$uniqueInstance;
    }

    public function SingletonOperation(){
        $this->singletonData = '修改单例类内部数据';
    }

    public function GetSigletonData()
    {
        return $this->singletonData;
    }

}

没错,核心就是这样一个单例类,没别的了。让静态变量保存实例化后的自己。当需要这个对象的时候,调用GetInstance()方法获得全局唯一的一个对象。

$singletonA = Singleton::GetInstance();
echo $singletonA->GetSigletonData(), PHP_EOL;

$singletonB = Singleton::GetInstance();

if ($singletonA === $singletonB) {
    echo '相同的对象', PHP_EOL;
}
$singletonA->SingletonOperation(); // 这里修改的是A
echo $singletonB->GetSigletonData(), PHP_EOL;

客户端的调用,我们会发现singletonA和singletonB是完全一样的对象。

  • 没错,从代码中就可以看出,单例最大的用途就是让我们的对象全局唯一。
  • 那么全局唯一有什么好处呢?有些类的创建开销很大,而且并不需要我们每次都使用新的对象,完全可以一个对象进行复用,它们并没有需要变化的属性或状态,只是提供一些公共服务。比如数据库操作类、网络请求类、日志操作类、配置管理服务等等
  • 曾经有过面试官问过,单例在PHP中到底是不是唯一的?如果在一个进程下,也就是一个fpm下,当然是唯一的。nginx同步拉起的多个fpm中那肯定就不是唯一的啦。一个进程一个嘛!
  • 单例模式的优点:对唯一实例的受控访问;缩小命名空间;允许对操作和表示的精化;允许可变数目的实例;比类操作更灵活。
  • Laravel中在IoC容器部分使用了单例模式。关于容器部分的内容我们会在将来的Laravel系列文章中讲解。我们可以在Illuminate\Container\Container类中找到singleton方法。它调用了bind方法中的getClosure方法。继续追踪会发现他们最终会调用Container的make或build方法来进行实例化类,不管是make还是build方法,他们都会有单例的判断,也就是判断类是否被实例化过或者在容器中已存在。build中的if (!$reflector->isInstantiable())。

公司越来越大,但我们的全部公司的花名册都只有一份(单例类),保存在我们的OA系统中。怕的就是各个部门拥有各自己的花名册后会产生混乱,比如更新不及时漏掉了其他部门新入职或者离职的员工。其他部门在需要的时候,可以去查看全部的花名册,也可以在全部花名册的基础上建立修改自己部门的部分。但是在OA系统中,其实他们修改的还是那一份总的花名册中的内容,大家维护的其实都是保存在OA系统服务器中的那唯一一份真实的花名册

UQ云商B2B2C系统
UQ云商B2B2C系统

UQCMS云商是一款B2B2C电子商务软件 ,非常适合初创的创业者,个人及中小型企业。程序采用PHP+MYSQL,模板采用smarty模板,二次开发,简单方便,无需学习其他框架就可以自行模板设计。永久免费使用,操作简单,安全稳定。支持PC+WAP+微信三种浏览方式,支持微信公众号。

下载
完整代码:https://github.com/zhangyue0503/designpatterns-php/blob/master/21.singleton/source/singleton.php

实例

既然上面说过数据库操作类和网络请求类都很喜欢用单例模式,那么我们就来实现一个Http请求类的单例模式的开发。记得在很早前做Android的时候,还没有现在这么多的框架,Http请求都是自己封装的,网上的教程中大部分也都是采取的单例模式。

缓存类图

缓存模板方法模式版

完整源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/21.singleton/source/singleton-http.php

Post();
$httpA->Get();

$httpB = new HttpService();
$httpB->Post();
$httpB->Get();

var_dump($httpA == $httpB);

说明

  • 是不是依然很简单,这里就不多说这种形式的单例了,我们说说另外几种形式的单例
  • 在Java等静态语言中,静态变量可以直接new对象,在声明1627297278206685.png

    instance = new HttpService();。这样可以省略掉GetInstance()方法,但是这个静态变量不管用不用都会直接实例化出来占用内存。这种单例就叫做饿汉式单例模式。

  • 我们的代码和例子很明显不是饿汉式的,这种形式叫做懒汉式。你要主动的来用GetInstance()获取,我才会创建对象。
  • 懒汉式在多线程的应用中,如java多线程或者PHP中使用swoole之后,会出现重复创建的问题,而且这多次创建的都不是同一个对象了。这时一般会使用双重检测来来确保全局还是只有唯一的一个对象。具体代码大家可以去自己找一下。饿汉式不会有问题,饿汉式本身就已经给静态属性赋值了,不会再改变。
  • 还有一种方式是静态内部类的创建方式。这种平常就不多见了,它的资源利用率高。将静态变量放在方法内,使静态变量成为方法内的变量而不是类中的变量。它可以让单例对象调用自身的静态方法和属性。

原文地址:https://juejin.cn/post/6844903990585458702

作者:硬核项目经理

推荐学习:《PHP视频教程

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

9

2026.01.20

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

59

2026.01.19

java用途介绍
java用途介绍

本专题整合了java用途功能相关介绍,阅读专题下面的文章了解更多详细内容。

80

2026.01.19

java输出数组相关教程
java输出数组相关教程

本专题整合了java输出数组相关教程,阅读专题下面的文章了解更多详细内容。

38

2026.01.19

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

10

2026.01.19

xml格式相关教程
xml格式相关教程

本专题整合了xml格式相关教程汇总,阅读专题下面的文章了解更多详细内容。

13

2026.01.19

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

17

2026.01.19

微信聊天记录删除恢复导出教程汇总
微信聊天记录删除恢复导出教程汇总

本专题整合了微信聊天记录相关教程大全,阅读专题下面的文章了解更多详细内容。

156

2026.01.18

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

162

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.9万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 8.6万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号