当前位置:首页 > PHP教程 > php应用 > 列表

【设计模式】PHP单例模式的应用场景和实现

发布:smiling 来源: PHP粉丝网  添加日期:2022-06-18 10:36:08 浏览: 评论:0 

摘要

什么是单例模式?

一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式。

为什么要使用单例?

处理资源访问冲突。

例如:往文件中打印日志的功能。

表示全局唯一类。

从业务概念上,如果有些数据在系统中只应保存一份,那就比较适合设计为单例类。例如:唯一递增 ID 号码生成器。

实现方式

实现php的单例模式需要三个步骤

* 一个静态成员变量,用来保存类。

* 为防止对象创建或者克隆,需要吧__construct和__clone声明为私有。

* 一个访问这个实例的公共的静态方法,通常为getInstance

  1. class single 
  2.  
  3.  
  4.     private static  $instance ; 
  5.  
  6.     private function __construct(){} 
  7.  
  8.     private function __clone(){} 
  9.  
  10.     public static function getInstance() { 
  11.  
  12.         if (emptyempty(self::$instance)) { 
  13.  
  14.             self::$instance = new single(); 
  15.  
  16.         } 
  17.  
  18.         return self::$instance
  19.  
  20.     } 
  21.  

给单例类加上一个方法,获取ID。一个全局唯一的id号码生成器就出现了。

  1. class single 
  2.  
  3.  
  4.     private  $id = 0; 
  5.  
  6.     private static  $instance ; 
  7.  
  8.     private function __construct(){} 
  9.  
  10.     private function __clone(){} 
  11.  
  12.     public static function getInstance() { 
  13.  
  14.         if (emptyempty(self::$instance)) { 
  15.  
  16.             self::$instance = new single(); 
  17.  
  18.         } 
  19.  
  20.         return self::$instance
  21.  
  22.     } 
  23.  
  24.     public function getId() { 
  25.  
  26.           
  27.  
  28.         return $this->id++; 
  29.  
  30.           
  31.  
  32.     } 
  33.  

真是无懈可击,那么在多线程的情况下发生了什么呢?

实现一个线程唯一的单例

这里不得不提到php的ts和nts版本区别,nts(Non Thread Safe)单线程构建,线程间共用缓存数据。ts(Thread Safe)具有多线程功能的构建,多个线程间使用不同的数据副本。

使用ts版本的php自动升级为线程安全模式,pthreads扩展只能安装在ts版本的php上。

pecl收录的最后一个版本pthreads就是基于php7.0,github上的pthreads项目也已经停止更新,感兴趣只能去7.0怀念历史了。

我在php-7.0.9-Win32-VC14-x64 这个版本下安装了pthreads扩展。

多线程的情况下,单例的范围就从进程唯一变成了线程唯一了。

  1. require 'single.php'
  2.  
  3. class Request extends Thread { 
  4.  
  5.     public $url
  6.  
  7.     public function __construct($url) { 
  8.  
  9.         $this->url = $url
  10.  
  11.     } 
  12.  
  13.     public function run() { 
  14.  
  15.         echo single::getInstance()->getId(); 
  16.  
  17.         echo "\n"
  18.  
  19.     } 
  20.  
  21.  
  22. $chG = new Request("www.google"); 
  23.  
  24. $chG ->start(); 
  25.  
  26. $chG->join(); 
  27.  
  28. echo $chG->getThreadId(); 
  29.  
  30. echo "\n"
  31.  
  32. $chB = new Request("www.baidu"); 
  33.  
  34. $chB ->start(); 
  35.  
  36. $chB->join(); 
  37.  
  38. echo $chB->getThreadId(); 
  39.  
  40. echo "\n"

这里创建了两个线程,但两次执行都可以获得从0开始的id,说明两个线程内的single类是两个不同的单例对象。

总结

实现php的单例模式需要三个步骤

* 一个静态成员变量,用来保存类。

* __construct和__clone声明为私有,防止创建或者克隆。

* 一个静态方法,通常为getInstance,用来访问这个实例。

php的多线程我也没用过,看起来是条不归路,不知道大家怎么看。

Tags: PHP单例模式 PHP应用场景

分享到: