PHP单例模式应用示例【多次连接数据库只实例化一次】


Posted in PHP onDecember 18, 2018

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

以前刚开始工作的时候经常连接数据库,每次用到数据库的时候就要用new进行实例并连接一次,当时因为连接数据库的次数不是很频繁,所以也没什么。后来主管对我说我现在这样每次都连接数据库的如果数据读取频繁的话对数据库和系统造成的压力会很大,让我想想办法能不能就连接一次数据库然后再次用到的时候就不用new一个新的连接了,当时怎么也没想到好的办法,知道最近学到了单例模式才恍然大悟,当时主管是引导我用单例模式的,只怪我以前对开发模式不懂。好了废话少说,下面来看单例模式:

单例模式(职责模式):

简单的说,一个对象(在学习设计模式之前,需要比较了解面向对象思想)只负责一个特定的任务;

单例类:

1、构造函数需要标记为private(访问控制:防止外部代码使用new操作符创建对象),单例类不能在其他类中实例化,只能被其自身实例化;

2、拥有一个保存类的实例的静态成员变量

3、拥有一个访问这个实例的公共的静态方法(常用getInstance()方法进行实例化单例类,通过instanceof操作符可以检测到类是否已经被实例化)

另外,需要创建__clone()方法防止对象被复制(克隆)

为什么要使用PHP单例模式?

1、php的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 使用单例模式, 则可以避免大量的new 操作消耗的资源。

2、如果系统中需要有一个类来全局控制某些配置信息, 那么使用单例模式可以很方便的实现. 这个可以参看ZF的FrontController部分。

3、在一次页面请求中, 便于进行调试, 因为所有的代码(例如数据库操作类db)都集中在一个类中, 我们可以在类中设置钩子, 输出日志,从而避免到处var_dump, echo

代码(官方文档中的):

<?php
class Singletons{
  // 保存类实例在此属性中
  private static $instance;
  // 构造方法声明为private,防止直接创建对象
  private function __construct()
  {
    echo 'Iam constructed';
  }
  // singleton 方法
  public static function singleton()
  {
    if (!isset(self::$instance)) {
      $c = __CLASS__;
      self::$instance =new$c;
    }
    return self::$instance;
  }
  // Example类中的普通方法
  public function bark()
  {
    echo 'Woof!';
  }
  // 阻止用户复制对象实例
  public function __clone()
  {
    trigger_error('Clone is not allowed.',E_USER_ERROR);
  }
}//endclass singletons
  //这个写法会出错,因为构造方法被声明为private
  //$test= new Singletons();
  // 下面将得到Example类的单例对象
  $test= Singletons::singleton();
  $test->bark();
  // 复制对象将导致一个E_USER_ERROR.
  $test_clone= clone $test;
?>

结果:

I am constructed!   Woof!
Fatal error:
Clone is not allowed. in E:\APMServ5.2.6\www\htdocs\Lee\myprogram\other\class\singletons.phpon line 31

以下内容源自网络(可以参考学习一下):

单例模式的三个要点:

(1). 需要一个保存类的唯一实例的静态成员变量:

 

private static $_instance;

(2). 构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义:

private function __construct()
 {
   $this->_db = pg_connect('xxxx');
 }
 private function __clone()
 {
 }//覆盖__clone()方法,禁止克隆

(3). 必须提供一个访问这个实例的公共的静态方法(通常为getInstance方法),从而返回唯一实例的一个引用

public static function getInstance()
{
   if(! (self::$_instance instanceof self) )
   {
     self::$_instance = new self();
   }
   return self::$_instance;
}

二、为什么要使用单例模式?

1、PHP缺点:

PHP语言是一种解释型的脚本语言,这种运行机制使得每个PHP页面被解释执行后,所有的相关资源都会被回收。也就是说,PHP在语言级别上没有办法让某个对象常驻内存,这和asp.NET、Java等编译型是不同的,比如在Java中单例会一直存在于整个应用程序的生命周期里,变量是跨页面级的,真正可以做到这个实例在应用程序生命周期中的唯一性。然而在PHP中,所有的变量无论是全局变量还是类的静态成员,都是页面级的,每次页面被执行时,都会重新建立新的对象,都会在页面执行完毕后被清空,这样似乎PHP单例模式就没有什么意义了,所以PHP单例模式我觉得只是针对单次页面级请求时出现多个应用场景并需要共享同一对象资源时是非常有意义的。

2、单例模式在PHP中的应用场合:

(1)、应用程序与数据库交互

一个应用中会存在大量的数据库操作,比如过数据库句柄来连接数据库这一行为,使用单例模式可以避免大量的new操作,因为每一次new操作都会消耗内存资源和系统资源。

(2)、控制配置信息

如果系统中需要有一个类来全局控制某些配置信息,那么使用单例模式可以很方便的实现.

三、如何实现单例模式?

1、普通的数据库访问例子:

<?php
 ......
 //初始化一个数据库句柄
 $db = new DB(...);
 //添加用户信息
 $db->addUserInfo(...);
 ......
//在函数中访问数据库,查找用户信息
function getUserInfo()
{
  $db = new DB(...);//再次new 数据库类,和数据库建立连接
  $db = query(....);//根据查询语句访问数据库
}
?>

2、应用单例模式对数据库进行操作:

<?php
 class DB
 {
   private $_db;
   private static $_instance;
   private function __construct(...)
   {
    $this->_db = pg_connect(...);//postgrsql
  }
  private function __clone() {}; //覆盖__clone()方法,禁止克隆
  public static function getInstance()
  {
    if(! (self::$_instance instanceof self) ) {
      self::$_instance = new self();
    }
    return self::$_instance;
  }
  public function addUserInfo(...)
  {
  }
   public function getUserInfo(...)
  {
  }
}
//test
$db = DB::getInstance();
$db->addUserInfo(...);
$db->getUserInfo(...);
?>

3、深入理解

<?php
 class db {
   public $conn;
   public static $sql;
   public static $instance=null;
   private function __construct(){
     require_once('db.config.php');
     $this->conn = mysql_connect($db['host'],$db['user'],$db['password']);
     if(!mysql_select_db($db['database'],$this->conn)){
      echo "失败";
    };
    mysql_query('set names utf8',$this->conn);
  }
  public static function getInstance(){
    if(is_null(self::$instance)){
      self::$instance = new db;
    }
    return self::$instance;
  }
  /**
   * 查询数据库
   */
  public function select($table,$condition=array(),$field = array()){
    $where='';
    if(!empty($condition)){
      foreach($condition as $k=>$v){
        $where.=$k."='".$v."' and ";
      }
      $where='where '.$where .'1=1';
    }
    $fieldstr = '';
    if(!empty($field)){
      foreach($field as $k=>$v){
        $fieldstr.= $v.',';
      }
       $fieldstr = rtrim($fieldstr,',');
    }else{
      $fieldstr = '*';
    }
    self::$sql = "select {$fieldstr} from {$table} {$where}";
    $result=mysql_query(self::$sql,$this->conn);
    $resuleRow = array();
    $i = 0;
    while($row=mysql_fetch_assoc($result)){
      foreach($row as $k=>$v){
        $resuleRow[$i][$k] = $v;
      }
      $i++;
    }
    return $resuleRow;
  }
  /**
   * 添加一条记录
   */
   public function insert($table,$data){
    $values = '';
    $datas = '';
    foreach($data as $k=>$v){
      $values.=$k.',';
      $datas.="'$v'".',';
    }
    $values = rtrim($values,',');
    $datas  = rtrim($datas,',');
    self::$sql = "INSERT INTO {$table} ({$values}) VALUES ({$datas})";
    if(mysql_query(self::$sql)){
      return mysql_insert_id();
    }else{
      return false;
    };
   }
   /**
   * 修改一条记录
   */
  public function update($table,$data,$condition=array()){
    $where='';
    if(!empty($condition)){
      foreach($condition as $k=>$v){
        $where.=$k."='".$v."' and ";
      }
      $where='where '.$where .'1=1';
    }
    $updatastr = '';
    if(!empty($data)){
      foreach($data as $k=>$v){
        $updatastr.= $k."='".$v."',";
      }
      $updatastr = 'set '.rtrim($updatastr,',');
    }
    self::$sql = "update {$table} {$updatastr} {$where}";
    return mysql_query(self::$sql);
  }
  /**
   * 删除记录
   */
   public function delete($table,$condition){
    $where='';
    if(!empty($condition)){
      foreach($condition as $k=>$v){
        $where.=$k."='".$v."' and ";
      }
      $where='where '.$where .'1=1';
    }
    self::$sql = "delete from {$table} {$where}";
    return mysql_query(self::$sql);
   }
  public static function getLastSql(){
    echo self::$sql;
  }
}
$db = db::getInstance();
//$list = $db->select('demo',array('name'=>'tom','password'=>'ds'),array('name','password'));
//echo $db->insert('demo',array('name'=>'最近你啦','password'=>'123'));
//echo $db->update('demo',array("name"=>'xxx',"password"=>'123'),array('id'=>1));
echo $db->delete('demo',array('id'=>'2'));
db::getLastSql();
echo "<pre>";
?>

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

PHP 相关文章推荐
在Zeus Web Server中安装PHP语言支持
Oct 09 PHP
PHP学习之PHP表达式
Oct 09 PHP
IIS php环境配置PHP5 MySQL5 ZendOptimizer phpmyadmin安装与配置
Nov 18 PHP
PHP 危险函数解释 分析
Apr 22 PHP
php循环语句 for()与foreach()用法区别介绍
Sep 05 PHP
深入Nginx + PHP 缓存详解
Jul 11 PHP
php接口数据加密、解密、验证签名
Mar 12 PHP
PHP统一页面编码避免乱码问题
Apr 09 PHP
PHP面向对象程序设计之类与反射API详解
Dec 02 PHP
PHP简单计算两个时间差的方法示例
Jun 20 PHP
php实现和c#一致的DES加密解密实例
Jul 24 PHP
微信公众号开发之获取位置信息php代码
Jun 13 PHP
PHP时间戳和日期相互转换操作实例小结
Dec 18 #PHP
PHP获取星期几的常用方法小结
Dec 18 #PHP
php往mysql中批量插入数据实例教程
Dec 12 #PHP
yii2 url重写并隐藏index.php方法
Dec 10 #PHP
php 处理png图片白色背景色改为透明色的实例代码
Dec 10 #PHP
php高清晰度无损图片压缩功能的实现代码
Dec 09 #PHP
PHP聊天室简单实现方法详解
Dec 08 #PHP
You might like
PHP实时显示输出
2008/10/02 PHP
PHP去掉从word直接粘贴过来的没有用格式的函数
2012/10/29 PHP
如何用PHP实现插入排序?
2013/04/10 PHP
PHP图像处理类库及演示分享
2015/05/17 PHP
PHP从二维数组得到N层分类树的实现代码
2016/10/11 PHP
PHP filesize函数用法浅析
2019/02/15 PHP
js中escape对应的C#解码函数 UrlDecode
2012/12/16 Javascript
12种不宜使用的Javascript语法整理
2013/11/04 Javascript
在jquery boxy中添加百度地图坐标拾取注意流程
2014/04/03 Javascript
基于javascript实现单选及多选的向右和向左移动实例
2015/07/25 Javascript
JavaScript实现将数组数据添加到Select下拉框的方法
2015/08/21 Javascript
纯JavaScript基于notie.js插件实现消息提示特效
2016/01/18 Javascript
JS中正则表达式只有3种匹配模式(没有单行模式)详解
2016/07/28 Javascript
利用yarn实现一个webpack+react种子
2016/10/25 Javascript
Bootstrap警告框(Alert)插件使用方法
2017/03/21 Javascript
微信小程序访问node.js接口服务器搭建教程
2017/04/25 Javascript
vue-cli构建项目使用 less的方法
2017/10/04 Javascript
JS获取一个表单字段中多条数据并转化为json格式
2017/10/17 Javascript
vue的.vue文件是怎么run起来的(vue-loader)
2018/12/10 Javascript
JavaScript中filter的用法实例分析
2019/02/27 Javascript
微信小程序云开发实现增删改查功能
2019/05/17 Javascript
JavaScript实现页面中录音功能的方法
2019/06/04 Javascript
Python cookbook(数据结构与算法)找出序列中出现次数最多的元素算法示例
2018/03/15 Python
解决python xlrd无法读取excel文件的问题
2018/12/25 Python
Python利用scapy实现ARP欺骗的方法
2019/07/23 Python
Python爬取豆瓣视频信息代码实例
2019/11/16 Python
Python flask框架端口失效解决方案
2020/06/04 Python
学习Python需要哪些工具
2020/09/04 Python
利用CSS3实现平移动画效果示例代码
2016/10/12 HTML / CSS
Original Penguin美国官网:布拉德皮特、强尼德普喜爱的服装品牌
2016/10/25 全球购物
莫斯科大型旅游休闲商品超市:Camping.ru
2020/09/16 全球购物
竞职演讲稿范文
2014/01/11 职场文书
校园创业策划书
2014/01/14 职场文书
采购部部长岗位职责
2014/02/06 职场文书
捐款感谢信
2015/01/20 职场文书
如何使用PyCharm及常用配置详解
2021/06/03 Python