侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

PHP单例模式是什么 php实现单例模式的方法

php  /  管理员 发布于 7年前   135

一、什么是单例模式?
1、含义   
   作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。
2、单例模式的三个要点:
(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、普通的数据库访问例子:

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

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

_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(...);   ?> 

 下面的代码是PDO操作数据库类的一个封装,采用了单例模式:

dsn = 'mysql:host='.$dbHost.';dbname='.$dbName;      $this->dbh = new PDO($this->dsn, $dbUser, $dbPasswd);      $this->dbh->exec('SET character_set_connection='.$dbCharset.', character_set_results='.$dbCharset.', character_set_client=binary');    } catch (PDOException $e) {      $this->outputError($e->getMessage());    }  }    /**   * 防止克隆   *    */  private function __clone() {}    /**   * Singleton instance   *    * @return Object   */  public static function getInstance($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset)  {    if (self::$_instance === null) {      self::$_instance = new self($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset);    }    return self::$_instance;  }    /**   * Query 查询   *   * @param String $strSql SQL语句   * @param String $queryMode 查询方式(All or Row)   * @param Boolean $debug   * @return Array   */  public function query($strSql, $queryMode = 'All', $debug = false)  {    if ($debug === true) $this->debug($strSql);    $recordset = $this->dbh->query($strSql);    $this->getPDOError();    if ($recordset) {      $recordset->setFetchMode(PDO::FETCH_ASSOC);      if ($queryMode == 'All') {        $result = $recordset->fetchAll();      } elseif ($queryMode == 'Row') {        $result = $recordset->fetch();      }    } else {      $result = null;    }    return $result;  }    /**   * Update 更新   *   * @param String $table 表名   * @param Array $arrayDataValue 字段与值   * @param String $where 条件   * @param Boolean $debug   * @return Int   */  public function update($table, $arrayDataValue, $where = '', $debug = false)  {    $this->checkFields($table, $arrayDataValue);    if ($where) {      $strSql = '';      foreach ($arrayDataValue as $key => $value) {        $strSql .= ", `$key`='$value'";      }      $strSql = substr($strSql, 1);      $strSql = "UPDATE `$table` SET $strSql WHERE $where";    } else {      $strSql = "REPLACE INTO `$table` (`".implode('`,`', array_keys($arrayDataValue))."`) VALUES ('".implode("','", $arrayDataValue)."')";    }    if ($debug === true) $this->debug($strSql);    $result = $this->dbh->exec($strSql);    $this->getPDOError();    return $result;  }    /**   * Insert 插入   *   * @param String $table 表名   * @param Array $arrayDataValue 字段与值   * @param Boolean $debug   * @return Int   */  public function insert($table, $arrayDataValue, $debug = false)  {    $this->checkFields($table, $arrayDataValue);    $strSql = "INSERT INTO `$table` (`".implode('`,`', array_keys($arrayDataValue))."`) VALUES ('".implode("','", $arrayDataValue)."')";    if ($debug === true) $this->debug($strSql);    $result = $this->dbh->exec($strSql);    $this->getPDOError();    return $result;  }    /**   * Replace 覆盖方式插入   *   * @param String $table 表名   * @param Array $arrayDataValue 字段与值   * @param Boolean $debug   * @return Int   */  public function replace($table, $arrayDataValue, $debug = false)  {    $this->checkFields($table, $arrayDataValue);    $strSql = "REPLACE INTO `$table`(`".implode('`,`', array_keys($arrayDataValue))."`) VALUES ('".implode("','", $arrayDataValue)."')";    if ($debug === true) $this->debug($strSql);    $result = $this->dbh->exec($strSql);    $this->getPDOError();    return $result;  }    /**   * Delete 删除   *   * @param String $table 表名   * @param String $where 条件   * @param Boolean $debug   * @return Int   */  public function delete($table, $where = '', $debug = false)  {    if ($where == '') {      $this->outputError("'WHERE' is Null");    } else {      $strSql = "DELETE FROM `$table` WHERE $where";      if ($debug === true) $this->debug($strSql);      $result = $this->dbh->exec($strSql);      $this->getPDOError();      return $result;    }  }    /**   * execSql 执行SQL语句   *   * @param String $strSql   * @param Boolean $debug   * @return Int   */  public function execSql($strSql, $debug = false)  {    if ($debug === true) $this->debug($strSql);    $result = $this->dbh->exec($strSql);    $this->getPDOError();    return $result;  }    /**   * 获取字段最大值   *    * @param string $table 表名   * @param string $field_name 字段名   * @param string $where 条件   */  public function getMaxValue($table, $field_name, $where = '', $debug = false)  {    $strSql = "SELECT MAX(".$field_name.") AS MAX_VALUE FROM $table";    if ($where != '') $strSql .= " WHERE $where";    if ($debug === true) $this->debug($strSql);    $arrTemp = $this->query($strSql, 'Row');    $maxValue = $arrTemp["MAX_VALUE"];    if ($maxValue == "" || $maxValue == null) {      $maxValue = 0;    }    return $maxValue;  }    /**   * 获取指定列的数量   *    * @param string $table   * @param string $field_name   * @param string $where   * @param bool $debug   * @return int   */  public function getCount($table, $field_name, $where = '', $debug = false)  {    $strSql = "SELECT COUNT($field_name) AS NUM FROM $table";    if ($where != '') $strSql .= " WHERE $where";    if ($debug === true) $this->debug($strSql);    $arrTemp = $this->query($strSql, 'Row');    return $arrTemp['NUM'];  }    /**   * 获取表引擎   *    * @param String $dbName 库名   * @param String $tableName 表名   * @param Boolean $debug   * @return String   */  public function getTableEngine($dbName, $tableName)  {    $strSql = "SHOW TABLE STATUS FROM $dbName WHERE Name='".$tableName."'";    $arrayTableInfo = $this->query($strSql);    $this->getPDOError();    return $arrayTableInfo[0]['Engine'];  }    /**   * beginTransaction 事务开始   */  private function beginTransaction()  {    $this->dbh->beginTransaction();  }    /**   * commit 事务提交   */  private function commit()  {    $this->dbh->commit();  }    /**   * rollback 事务回滚   */  private function rollback()  {    $this->dbh->rollback();  }    /**   * transaction 通过事务处理多条SQL语句   * 调用前需通过getTableEngine判断表引擎是否支持事务   *   * @param array $arraySql   * @return Boolean   */  public function execTransaction($arraySql)  {    $retval = 1;    $this->beginTransaction();    foreach ($arraySql as $strSql) {      if ($this->execSql($strSql) == 0) $retval = 0;    }    if ($retval == 0) {      $this->rollback();      return false;    } else {      $this->commit();      return true;    }  }  /**   * checkFields 检查指定字段是否在指定数据表中存在   *   * @param String $table   * @param array $arrayField   */  private function checkFields($table, $arrayFields)  {    $fields = $this->getFields($table);    foreach ($arrayFields as $key => $value) {      if (!in_array($key, $fields)) {        $this->outputError("Unknown column `$key` in field list.");      }    }  }    /**   * getFields 获取指定数据表中的全部字段名   *   * @param String $table 表名   * @return array   */  private function getFields($table)  {    $fields = array();    $recordset = $this->dbh->query("SHOW COLUMNS FROM $table");    $this->getPDOError();    $recordset->setFetchMode(PDO::FETCH_ASSOC);    $result = $recordset->fetchAll();    foreach ($result as $rows) {      $fields[] = $rows['Field'];    }    return $fields;  }    /**   * getPDOError 捕获PDO错误信息   */  private function getPDOError()  {    if ($this->dbh->errorCode() != '00000') {      $arrayError = $this->dbh->errorInfo();      $this->outputError($arrayError[2]);    }  }    /**   * debug   *    * @param mixed $debuginfo   */  private function debug($debuginfo)  {    var_dump($debuginfo);    exit();  }    /**   * 输出错误信息   *    * @param String $strErrMsg   */  private function outputError($strErrMsg)  {    throw new Exception('MySQL Error: '.$strErrMsg);  }    /**   * destruct 关闭数据库连接   */  public function destruct()  {    $this->dbh = null;  }}?>

调用方法:

query("select count(*) frome table");$db->destruct();?>

以上就是本文的全部内容,希望对大家学习php程序设计有所帮助。

您可能感兴趣的文章:

  • php 单例模式详细介绍及实现源码
  • php基于单例模式封装mysql类完整实例
  • PHP设计模式之工厂模式与单例模式
  • PHP基于单例模式编写PDO类的方法
  • php设计模式之单例模式代码
  • php单例模式的简单实现方法
  • php面向对象值单例模式
  • PHP基于单例模式实现的数据库操作基类
  • PHP基于单例模式实现的mysql类
  • PHP单例模式详细介绍
  • 浅析php单例模式
  • php单态设计模式(单例模式)实例
  • PHP单例模式详解及实例代码


  • 上一条:
    php基于CodeIgniter实现图片上传、剪切功能
    下一条:
    PHP pear安装配置教程
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 用Time Warden监控PHP中的代码处理时间(0个评论)
    • 在PHP中使用array_pop + yield实现读取超大型目录功能示例(0个评论)
    • Property Hooks RFC在PHP 8.4中越来越接近现实(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(95个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-11
    • 2017-12
    • 2018-01
    • 2018-02
    • 2018-03
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-09
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-09
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客