加入收藏 | 设为首页 | 会员中心 | 我要投稿 周口站长网 (https://www.0394zz.cn/)- 数据采集、智能营销、经验、云计算、专属主机!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

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

发布时间:2022-07-15 12:26:12 所属栏目:PHP教程 来源:互联网
导读:PHP单例模式是什么?这篇文章主要介绍了php实现单例模式的方法,告诉大家为什么使用单例模式,感兴趣的朋友可以参考一下。 一、什么是单例模式? 1、含义 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个
  PHP单例模式是什么?这篇文章主要介绍了php实现单例模式的方法,告诉大家为什么使用单例模式,感兴趣的朋友可以参考一下。
 
  一、什么是单例模式?
 
  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、普通的数据库访问例子:
 
  <?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(...);   
     
  ?>  
  下面的代码是PDO操作数据库类的一个封装,采用了单例模式:
 
  <?php
  /**
   * MyPDO
   */
  class MyPDO
  {
    protected static $_instance = null;
    protected $dbName = '';
    protected $dsn;
    protected $dbh;
      
    /**
     * 构造
     *  
     * @return MyPDO
     */
    private function __construct($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset)
    {
      try {
        $this->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;
    } 

(编辑:周口站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读