PHP单例模式定义与使用实例详解


Posted in PHP onFebruary 06, 2017

本文实例讲述了PHP单例模式定义与使用。分享给大家供大家参考,具体如下:

先简单的介绍一下单例模式。单例模式就是在应用程序中保持某一个类实例只存在一个,而且不可以受外部环境的影响而生成这个类的第二个实例。它的优点,实际点见,如果在WEB开发中,保持单一个数据操作类实例的存在,可以减少不必要的多余连接数据库资源的消耗,对于大型的软件开发来说,可以使用单例来维持程序的状态,使不同操作实现同步,因为单例一直占据内存,而从不会有副本。

而对于PHP,使用单例最常用的场合莫过于写一个数据库操作类。不过在PHP中实现单例,有以下规则:

1)单例类必须拥有一个现式声明的构造函数,并且是私有的。

2)单例类必须有一个静态变量来存储类的实例,这样可以保持这个单例类就只有那么一个实例。

3)单例类必须提供一个静态方法,供其他所有的对象应用这个单例。

为什么要满足以上三个条件呢:

1)因为单例类在整个应用程序运行时,只能被创造一次,而且这种创造是不是通过外部调用而完成,而是自身完成。所以单例类是自己实例化自己,所以其构造函数必须是私有。任何其他外部对象都不可以再次构造一个单例类的副本。

2)因为单例类只能够自己实例化自己,而又要为所有外部应用提供自己的实例,所以类内部必须有一个可供外界访问,而又是唯一不变的访问存储对象点,所以要提供一个静态变量去存储单例类自己实例化自己的那个实例对象。

3)因为单例类的构造函数是私有的,所以单例类必须提供一个外部接口供外部环境调用单例类,所以必须有一个静态方法,它可以初始化单例类或者返回单例类的对象的引用。

一个简单的例子:

class DB{
   private $_link;
   //   保持单例类的静态变量
   static $_instance;
   //   私有的构造函数
   private function __construct(){
       $this->_link = @mysqli_connect(__HOST__, __USER__, __PASSWORD__, __DATABASE__);
       if(! ($this->_link)){
          echo 'Something wrong occurs on the database connection!';  
       }
   }
   //   防止单例类被克隆
   private function __clone(){}
   //   外界访问单例类实例的接口
   public static function getInstance(){
       if(! (self::$_instance instanceof self)){
          self::$_instance = new self();
       }
       return self::$_instance;
   }
}

注意,以上定义的一个 __clone() 函数,防止单例类对象被克隆。

以下也是一个简单的数据库操作类的单例,供参考:

class DB {
   /**
    * the database connection
    * @var   resource
    * @access private
    */
   private $_link;
   /**
    * the static instance of single db
    * @var   object
    * @access static
    */
   static $_instance;
   /**
    * construct the single object
    * @return null
    * @access private
    */
   private function __construct(){
       $this->_link = @mysqli_connect(__HOST__, __USER__, __PASSWORD__, __DATABASE__);
       if(! ($this->_link)){
          echo 'Something wrong occurs on the database connection!';  
       }
   }
   /**
    * empty clone
    * @return null
    * @access private
    */
   private function __clone(){}
   /**
    * for other object to get the instance of db
    * @return self::instance
    * @access public
    */
   public static function getInstance(){
       if(! (self::$_instance instanceof self)){
          self::$_instance = new self();
       }
       return self::$_instance;
   }
   /**
    * query
    * @param  sql string
    * @param  message string
    * @return   resource
    * @access public
    */
   public function query($sql,$message){
       $result = @mysqli_query($this->$_link, $sql) or die($message . mysqli_error($this->$_link));
       return $result;
   }
   /**
    * mysqli_num_rows
    * @param  result resource
    * @return   int
    * @access public
    */
   public function num($result){
       return @mysqli_num_rows($result);
   }
   /**
    * mysqli_fetch_array
    * @param  result resource
    * @return   array
    * @access public
    */
   public function fetchArr($result){
       return @mysqli_fetch_array($result);
   }
   /**
    * mysqli_insert_id
    * @return   int
    * @access public
    */
   public function last_id(){
       return @mysqli_insert_id($this->_link);   
   }
   /**
    * close the database connection
    * @param  result resource
    * @return   null
    * @access public
    */
   public function close(){
       @mysqli_close($this->_link);
   }
   /**
    * fetch once result from the specific sql query
    * @param  sql string
    * @param  message string
    * @return   array
    * @access public
    */
   public function fetchArrOnce($sql, $message){
       $result = $this->query($sql, $message);
       $row = $this->fetchArr($result);
       return $row;
   }
   /**
    * fetch all results from the specific sql query
    * @param  sql string
    * @param  message string
    * @return   array
    * @access public
    */
   public function fetchArrMore($sql, $message){
       $result = $this->query($sql, $message);
       $moreRow = array();
       while($row = $this->fetchArr($result)){
          $moreRow[] = $row;
       }
       return $moreRow;
   }
   /**
    * fetch the number of results from the specific sql query
    * @param  sql string
    * @param  message string
    * @return   array
    * @access public
    */
   public function fetchNum($sql, $message){
       $result = $this->query($sql, $message);
       $resultNum = $this->num($result);
       return $resultNum;
   }
   /**
    * mysqli_prepare
    * @param  sql string
    * @return   stmt object
    * @access public
    */
   public function prepare($sql){
       return @mysqli_prepare($this->_link, $sql);
   }
   /**
    * mysqli_stmt_execute
    * @param  stmt object
    * @param  message string
    * @return   bool
    * @access public
    */
   public function stmt_execute($stmt, $message){
       @mysqli_stmt_execute($stmt) or die($message . mysqli_error($this->_link));
   }
}

使用:

define("__HOST__", "localhost");
define("__USER__", "root");
define("__PASSWORD__", "");
define("__DATABASE__", "eee");
$db = DB::getInstance();

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP 日期加减的类,很不错
Oct 10 PHP
如何用php生成扭曲及旋转的验证码图片
Jun 07 PHP
PHP 关于访问控制的和运算符优先级介绍
Jul 08 PHP
php中require和require_once的区别说明
Feb 27 PHP
查找php配置文件php.ini所在路径的二种方法
May 26 PHP
VB中的RasEnumConnections函数返回632错误解决方法
Jul 29 PHP
php简单实现多字节字符串翻转的方法
Mar 31 PHP
PHP将Excel导入数据库及数据库数据导出至Excel的方法
Jun 24 PHP
php获取从百度、谷歌等搜索引擎进入网站关键词的方法
Jul 08 PHP
关于php中的json_encode()和json_decode()函数的一些说明
Nov 20 PHP
PHP设计模式(五)适配器模式Adapter实例详解【结构型】
May 02 PHP
KindEditor在php环境下上传图片功能集成的方法示例
Jul 20 PHP
PHP第三方登录―QQ登录实现方法
Feb 06 #PHP
php计算给定日期所在周的开始日期和结束日期示例
Feb 06 #PHP
PHP实现判断数组是一维、二维或几维的方法
Feb 06 #PHP
php中get_magic_quotes_gpc()函数说明
Feb 06 #PHP
PHP数字前补0的自带函数sprintf 和number_format的用法(详解)
Feb 06 #PHP
浅谈php中fopen不能创建中文文件名文件的问题
Feb 06 #PHP
PHP 类与构造函数解析
Feb 06 #PHP
You might like
php判断用户是否关注微信公众号
2016/07/22 PHP
常用参考资料(手册)下载或者链接
2006/07/22 Javascript
javascript 关于# 和 void的区别分析
2009/10/26 Javascript
JavaScript 联动的无限级封装类,数据采用非Ajax方式,随意添加联动
2010/06/29 Javascript
JSChart轻量级图形报表工具(内置函数中文参考)
2010/10/11 Javascript
Jquery设置attr的disabled属性控制某行显示或者隐藏
2014/09/25 Javascript
JS对字符串编码的几种方式使用指南
2015/05/14 Javascript
Node.js中Request模块处理HTTP协议请求的基本使用教程
2016/03/31 Javascript
jQuery实现图片向左向右切换效果的简单实例
2016/05/18 Javascript
jQuery制作网页版选项卡
2016/07/28 Javascript
bootstrap快速制作后台界面
2016/12/05 Javascript
简单实现jQuery手风琴效果
2017/08/18 jQuery
自制简易打赏功能的实例
2017/09/02 Javascript
Vue 之孙组件向爷组件通信的实现
2019/04/23 Javascript
JavaScript 预解析的4种实现方法解析
2019/09/03 Javascript
vue实现员工信息录入功能
2020/06/11 Javascript
python局部赋值的规则
2013/03/07 Python
python with statement 进行文件操作指南
2014/08/22 Python
python微信公众号开发简单流程
2018/03/23 Python
分享8个非常流行的 Python 可视化工具包
2019/06/05 Python
使用python爬取抖音视频列表信息
2019/07/15 Python
Python Des加密解密如何实现软件注册码机器码
2020/01/08 Python
Django 博客实现简单的全文搜索的示例代码
2020/02/17 Python
Python判断字符串是否为空和null方法实例
2020/04/26 Python
Pycharm2020.1安装无法启动问题即设置中文插件的方法
2020/08/07 Python
pandas使用函数批量处理数据(map、apply、applymap)
2020/11/27 Python
Pandas之缺失数据的实现
2021/01/06 Python
探索HTML5本地存储功能运用技巧
2016/03/02 HTML / CSS
Antonioli美国在线商店:时尚前卫奢华
2019/07/29 全球购物
伦敦新晋轻奢耳饰潮牌:Tada & Toy
2020/05/25 全球购物
4s店机修工岗位职责
2013/12/20 职场文书
公司租房协议书
2014/10/14 职场文书
2014年党的群众路线学习心得体会
2014/11/05 职场文书
2014年政务公开工作总结
2014/12/09 职场文书
vue实现简单数据双向绑定
2021/04/28 Vue.js
python+opencv实现目标跟踪过程
2022/06/21 Python