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 显示客户端IP与服务器IP的代码
Oct 12 PHP
PHP file_get_contents设置超时处理方法
Sep 30 PHP
一组PHP可逆加密解密算法实例代码
Jan 21 PHP
PHP遍历数组的三种方法及效率对比分析
Feb 12 PHP
php浏览历史记录的方法
Mar 10 PHP
WordPress中给媒体文件添加分类和标签的PHP功能实现
Dec 31 PHP
PHP/HTML混写的四种方式总结
Feb 27 PHP
php简单实现单态设计模式的方法分析
Jul 28 PHP
PHP实现超简单的SSL加密解密、验证及签名的方法示例
Aug 28 PHP
ThinkPHP框架实现导出excel数据的方法示例【基于PHPExcel】
May 12 PHP
PHP goto语句用法实例
Aug 06 PHP
解决laravel5中auth用户登录其他页面获取不到登录信息的问题
Oct 08 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实现登陆验证码(类似条行码状)
2006/10/09 PHP
PHP多线程抓取网页实现代码
2010/07/22 PHP
PHP中限制IP段访问、禁止IP提交表单的代码
2011/04/23 PHP
php file_get_contents抓取Gzip网页乱码的三种解决方法
2013/11/12 PHP
header导出Excel应用示例
2014/01/24 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
2017/09/16 PHP
JS getMonth()日期函数的值域是0-11
2010/02/15 Javascript
JavaScript面向对象程序设计三 原型模式(上)
2011/12/21 Javascript
JavaScript中json对象和string对象之间相互转化
2012/12/26 Javascript
从零学JS之你需要了解的几本书
2014/05/19 Javascript
javascript实现在指定元素中垂直水平居中
2015/09/13 Javascript
基于jQuery仿淘宝产品图片放大镜代码分享
2020/06/23 Javascript
Bootstrap页面布局基础知识全面解析
2016/06/13 Javascript
利用Angularjs和原生JS分别实现动态效果的输入框
2016/09/01 Javascript
JS实现图片居中悬浮效果
2017/12/25 Javascript
element-ui使用导航栏跳转路由的用法详解
2018/08/22 Javascript
ES6 fetch函数与后台交互实现
2018/11/14 Javascript
Node.js assert断言原理与用法分析
2019/01/04 Javascript
微信小程序扫描二维码获取信息实例详解
2019/05/07 Javascript
Node.js API详解之 dns模块用法实例分析
2020/05/15 Javascript
vantUI 获得piker选中值的自定义ID操作
2020/11/04 Javascript
多线程爬虫批量下载pcgame图片url 保存为xml的实现代码
2013/01/17 Python
对Xpath 获取子标签下所有文本的方法详解
2019/01/02 Python
Python OpenCV中的resize()函数的使用
2019/06/20 Python
python框架django项目部署相关知识详解
2019/11/04 Python
Python如何输出百分比
2020/07/31 Python
Zavvi美国:英国娱乐之家
2017/03/19 全球购物
印度低票价航空公司:GoAir
2017/10/11 全球购物
狼和鹿教学反思
2014/02/05 职场文书
优秀语文教师事迹
2014/05/18 职场文书
2014世界杯球队球队口号
2014/06/05 职场文书
财务助理岗位职责范本
2014/10/09 职场文书
2016年中学清明节活动总结
2016/04/01 职场文书
求职自我评价参考范文
2019/05/16 职场文书
详解Vue slot插槽
2021/11/20 Vue.js
SpringBoot全局异常处理方案分享
2022/05/25 Java/Android