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安装全攻略:APACHE
Oct 09 PHP
PHP+ajax 无刷新删除数据
Feb 20 PHP
php中强制下载文件的代码(解决了IE下中文文件名乱码问题)
May 09 PHP
php+mysql实现无限分类实例详解
Jan 15 PHP
PHP判断手机是IOS还是Android
Dec 09 PHP
Yii2 输出xml格式数据的方法
May 03 PHP
浅谈socket同步和异步、阻塞和非阻塞、I/O模型
Dec 15 PHP
PHP实现登陆表单提交CSRF及验证码
Jan 24 PHP
thinkPHP+ajax实现统计页面pv浏览量的方法
Mar 15 PHP
PHP从零开始打造自己的MVC框架之入口文件实现方法详解
Jun 03 PHP
PHP面向对象程序设计之构造方法和析构方法详解
Jun 13 PHP
Laravel框架实现即点即改功能的方法分析
Oct 31 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上传图片、删除图片实现代码
2010/05/12 PHP
比较时间段一与时间段二是否有交集的php函数
2011/05/31 PHP
PHP类型约束用法示例
2016/09/28 PHP
Zend Framework入门教程之Zend_Mail用法示例
2016/12/08 PHP
PHP面向对象程序设计OOP继承用法入门示例
2016/12/27 PHP
Referer原理与图片防盗链实现方法详解
2019/07/03 PHP
JS类定义原型方法的两种实现的区别评论很多
2007/09/12 Javascript
ExtJS自定义主题(theme)样式详解
2013/11/18 Javascript
基于JS实现Android,iOS一个手势动画效果
2016/04/27 Javascript
JS上传图片预览插件制作(兼容到IE6)
2016/08/07 Javascript
javascript经典特效分享 手风琴、轮播图、图片滑动
2016/09/14 Javascript
原生JS实现在线问卷调查投票特效
2017/01/03 Javascript
Vue实例简单方法介绍
2017/01/20 Javascript
vue中如何动态绑定图片,vue中通过data返回图片路径的方法
2018/02/07 Javascript
解决Vue.js 2.0 有时双向绑定img src属性失败的问题
2018/03/14 Javascript
基于jQuery.i18n实现web前端的国际化
2018/05/04 jQuery
在移动端使用vue-router和keep-alive的方法示例
2018/12/02 Javascript
JavaScript简单实现动态改变HTML内容的方法示例
2018/12/25 Javascript
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
2019/04/28 jQuery
自定义javascript验证框架示例【附源码下载】
2019/05/31 Javascript
微信小程序如何修改radio和checkbox的默认样式和图标
2019/07/24 Javascript
JavaScript创建、读取和删除cookie
2019/09/03 Javascript
jquery 插件重新绑定的处理方法分析
2019/11/23 jQuery
详解jQuery中的prop()使用方法
2020/01/05 jQuery
[05:14]辉夜杯主赛事第二日 RECAP精彩回顾
2015/12/27 DOTA
[58:57]2018DOTA2亚洲邀请赛3月29日小组赛B组 Effect VS VGJ.T
2018/03/30 DOTA
[03:08]迎霜节狂欢!2018年迎霜节珍藏Ⅰ一览
2018/12/25 DOTA
利用Python实现颜色色值转换的小工具
2016/10/27 Python
python 密码学示例——理解哈希(Hash)算法
2020/09/21 Python
马来西亚户外装备商店:PTT Outdoor
2019/07/13 全球购物
2014年学习全国道德模范事迹思想汇报
2014/09/15 职场文书
2016大学生就业指导课心得体会
2016/01/15 职场文书
Python使用protobuf序列化和反序列化的实现
2021/05/19 Python
Pytorch反向传播中的细节-计算梯度时的默认累加操作
2021/06/05 Python
springboot新建项目pom.xml文件第一行报错的解决
2022/01/18 Java/Android
Python中request的基本使用解决乱码问题
2022/04/12 Python