PHP 单例模式如何实现,PHP 单例模式的实现
单例设计模式为了解决在一个应用中只有一个实例【比如数据库实例】,并且禁止clone 复制
在PHP中可以继承单例模式来使用单例模式的特性,避免每次创建一个类都要创建一个对象
但是上面参考链接其实也有一点问题 【然后我自己添加了一个回答:) 看到的点个赞奥】
一般单例模式的实现
class Singleton{ private static $instance; private function __construct(){} final protected function __clone(){} #不允许被重写并且会被子类继承 public static function getInstance(){ if (! self::$instance instanceof self) { self::$instance = new self(); } return self::$instance; } } // $s = new Singleton();#Fatal error: Call to private Singleton::__construct() $s1 = Singleton::getInstance(); $s2 = Singleton::getInstance(); var_dump($s1,$s2); #object(Singleton)#1 (0) { } object(Singleton)#1 (0) { } #测试出来两个实例是同一个对象 #测试clone 对象,会报错,说明真的只有一个对象存在于应用中 // $s2 = clone $s1; #Fatal error: Call to protected Singleton::__clone()
上面的代码看上去没有任何问题但是如果我们想让单例模式可以被继承,让子类也具有单例模式的特性,就会出错
Java 中构造函数是私有的不能被继承,默认情况下Java的子类会在构造函数中调用父类的无参数构造方法
PHP 可以继承,哪怕父类是私有构造器
下面是测试 PHP代码
class A extends Singleton
{
}
$a = new A();#Fatal error: Call to private Singleton::__construct() 调用了父类的private 的构造函数
#如果子类中没有构造函数就使用父类的构造方法,如果有自己的构造方法,就不会自动调用父类的构造方法,需要显式调用 parent::__construct();
#所以还是需要调用 静态方法获得实例
$a = A::getInstance();
var_dump($a);#object(Singleton)#1 (0){ } #出毛病了,实例化之后还是Singleton对象
#解决方法使用PHP动态绑定,关键字static 除了静态方法之外下面罗列动态绑定的特性
1) 在非静态环境下,所调用的类即为该对象实例所属的类【就代表了这个实例】
2) 由于 $this-> 会在同一作用范围内尝试调用私有方法,而 static:: 则可能给出不同结果。 [$this 可以调用同一范围的私有变量方法 static 相当于类名 比如说 A::$instance,就不行]
如果 static::function 或者static::$instance 调用的是同一个类里面的方法不管是不是private 都ok 但是如果是不同类的 就会报错
猜测性小结: 只要static 调用的元素不在同一个类里面 private 就会报错
3) 另一个区别是 static:: 只能用于静态属性 不是方法【方法都可以调用】。
所以最后单例模式可以写成如下格式
需要注意的使用self::或者__CLASS__对当前类的静态引用,取决于定义当前方法所在的类
#定义一个抽象类 被其他类继承 abstract class Singleton{ protected static $instance; // 这里必须是protected 如果要让子类继承 其次protected才能被 static 调用 private function __construct(){} final protected function __clone(){} public static function getInstance(){ if (! static::$instance instanceof static) { static::$instance = new static(); } return static::$instance; } } class A extends Singleton{ protected static $instance; #必须重定义 否则就是父类的$instance } //如果子类里面重新定义了构造函数 自然它就算不上单例模式 class B extends A{ protected static $instance; } $a = A::getInstance(); $b = B::getInstance(); $c = B::getInstance(); $d = A::getInstance(); $e = A::getInstance(); var_dump($a,$b,$c,$d,$e); #object(A)#1 (0) { } #object(B)#2 (0) { } #object(B)#2 (0) { } #object(A)#1 (0) { } #object(A)#1 (0) { }
小结:
public static function getInstance(){ if (! static::$instance instanceof static) { static::$instance = new static(); } return static::$instance; } # 上面方法中必须使用static::$instance 不能使用self::$instance 的原因是子类动态调用的是子类的静态属性 # 静态属性必须是 protected 原因是 动态调用关键字static 调动不是在一个原生类里面的private的属性时相当于直接 类名::$instance # 子类必须重定义 protected static $instance; 否则使用的是父类的静态属性
PHP 单例模式如何实现,PHP 单例模式的实现相关推荐
- IOS swift项目的单例模式.swift5以后的单例模式
IOS swift项目的单例模式.swift5以后的单例模式 不能继承NSObject 第一种写法,最简单 class SoundTools{static let sharedInstance = S ...
- 设计模式-单例模式-注册式单例模式-枚举式单例模式和容器式单例模式在Java中的使用示例
场景 设计模式-单例模式-饿汉式单例模式.懒汉式单例模式.静态内部类在Java中的使用示例: 设计模式-单例模式-饿汉式单例模式.懒汉式单例模式.静态内部类在Java中的使用示例_霸道流氓气质的博客- ...
- java利用单例模式存储参数_java单例模式使用及注意事项
strtok函数实际上是要把第一个参数的字符串进行修改的.因为这个原因这个字符串的存储位置就不能是只读的, 也就是说不能存放在常量区.在使用char* aa ="abcdefg"; ...
- java单例模式的应用_java单例模式的简单应用例子
单例模式:用于保证在程度的运行期间某个类有且只有一个实例 优势:在于尽可能节约资源 应用场景:还不太懂,希望懂的前辈们补充 -------------------- 通过修改构造方法的访问权限实现单例 ...
- 单例模式讨论篇:单例模式与垃圾回收
出处:http://blog.csdn.net/zhengzhb/article/details/7331354 Jvm的垃圾回收机制到底会不会回收掉长时间不用的单例模式对象,这的确是一个比较有争 ...
- java spring 单例模式,spring中的单例模式
spring依赖注入的bean默认都是单例模式,他们是怎么创建的? 在AbstractBeanFactory类中的getBean方法中调用了getSingleton()方法来创建bean: @Null ...
- 用java创建一个单例模式,采用Java实现单例模式
一. 背景 单例模式是指在内存中只会创建且仅创建一次对象的设计模式.在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用 ...
- python最简单单例模式_5种Python单例模式的实现方式
本文为大家分享了Python创建单例模式的5种常用方法,供大家参考,具体内容如下 所谓单例,是指一个类的实例从始至终只能被创建一次. 方法1: 如果想使得某个类从始至终最多只有一个实例,使用__new ...
- 单例模式 java 实现_单例模式
我们知道单例模式,其实就是返回一个被调用类的实例. 在频繁的进行实例(Instance)创建过程,难免过多的进行new InstanceName():我们可以只通过调用一个方法解决. 在进行设计模式的 ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,单例模式阅读总结【单例模式不同写法、在JDK中的应用】~整起
无论是哪种设计模式,自己啃哪本书哪个博客去学,都会考虑最起码的两个问题: 我到底该咋用这种设计模式呀,直接把书上的.百度上的.博客上-的程序们抄过来? 那我该咋用呢?就算把人家程序抄过来,抄过来放在哪 ...
最新文章
- dz seo插件_河北seo优化网络推广报价单
- Tool之curl:curl的简介、安装、使用方法之详细攻略
- python中异常的处理及断言,包括异常类型、异常捕获、主动跑出异常和断言
- mysql 中文字段名_10个MySQL的数据库技巧~
- java xml dom getelementbyid,DOM中常见的元素获取方式
- MySQL8.0二进制免编译部署过程详解(二)
- matebook14支持触摸屏吗_matebook 14有触屏吗
- MySQL数据库的主键和外键详解
- keytool命令详解 自签名证书
- 【ICCV2019论文阅读】PU-GAN:点云上采样对抗网络
- matlab 绘图 模板,【科研绘图】MATLAB可视化代码模板
- linux mbr转换成gpt分区格式,GPT分区格式与MBR格式互相转换的方法
- hazelcast 搭建_使用HazelCast实现Spring Config Server配置
- Flink实战——每隔5秒,统计最近10秒的窗口数据
- 白盒测试方法 + 实战
- 充分利用计算机在教学中的作用,浅谈多媒体在教学中的作用
- 议程速递 | 7月27日分论坛议程一览
- 计算机仿真在机械行业中的应用,计算机仿真技术在机械行业中的应用
- 疯狂砸钱营销,大力推广新品,香飘飘为啥还是留不住消费者?
- python灰产_python入门之编码风格规范分享