用单例模式封装实现一个数据库类

来源:互联网 发布:淘宝空间图片协议 编辑:程序博客网 时间:2024/05/23 12:28

使用单例模式的出发点:  

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

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

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

创造单例注意:

  1、一个雷只能有一个类对象(只能实例化一个对象)

  2、它必须自己创建这个实例

  3、它必须自行向整个系统提供这个实例

  4、构造函数和克隆函数必须声明为私有的,这是为了防止外部程序 new 类从而失去单例模式的意义

  5、 getInstance()方法必须声明为公有的,必须调用此方法以返回唯一实例的一个引用

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

  7、PHP的单例模式是相对而言的,因为PHP的解释运行机制使得每个PHP页面被解释执行后,所有的相关资源都会被回收

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

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

代码如下:

复制代码
 1 <?php 2 class Danli 3 { 4  5 //保存类实例的静态成员变量 6     private static $_instance; 7  8 //private标记的构造方法 9     private function __construct()10     {11         echo 'This is a Constructed method;';12     }13 14 //创建__clone方法防止对象被复制克隆15     public function __clone()16     {17         trigger_error('Clone is not allow!', E_USER_ERROR);18     }19 20 //单例方法,用于访问实例的公共的静态方法21     public static function getInstance()22     {23         if (!(self::$_instance instanceof self)) {24             self::$_instance = new self;25         }26         return self::$_instance;27     }28 29     public function test()30     {31         echo '调用方法成功';32     }33 34 }35 36 /*用new实例化private标记构造函数的类会报错37 $danli = new Danli();38 39 复制(克隆)对象将导致一个E_USER_ERROR40 $danli_clone = clone $danli;41 */42 43 44 //正确方法,用双冒号::操作符访问静态方法获取实例45 $danli = Danli::getInstance();46 $danli->test();47 ?>
复制代码

 

运用单例模式实现一个数据库类:

复制代码
 1 <?php 2 class DBHelper 3 { 4     private $link; 5     static private $_instance; 6  7     // 连接数据库 8     private function __construct($host, $username, $password) 9     {10         $this->link = mysql_connect($host, $username, $password);11         $this->query("SET NAMES 'utf8'", $this->link);12         //echo mysql_errno($this->link) . ": " . mysql_error($link). "n";13         //var_dump($this->link);14         return $this->link;15     }16     private function __clone()17     {18     }19     public static function get_class_nmdb($host, $username, $password)20     {21         //$connector = new nmdb($host, $username, $password);22         //return $connector;23 24         if (FALSE == (self::$_instance instanceof self)) {25             self::$_instance = new self($host, $username, $password);26         }27         return self::$_instance;28     }29     // 连接数据表30     public function select_db($database)31     {32         $this->result = mysql_select_db($database);33         return $this->result;34     }35     // 执行SQL语句36     public function query($query)37     {38         return $this->result = mysql_query($query, $this->link);39     }40     // 将结果集保存为数组41     public function fetch_array($fetch_array)42     {43         return $this->result = mysql_fetch_array($fetch_array, MYSQL_ASSOC);44     }45     // 获得记录数目46     public function num_rows($query)47     {48         return $this->result = mysql_num_rows($query);49     }50     // 关闭数据库连接51     public function close()52     {53         return $this->result = mysql_close($this->link);54     }55 }56 $connector = DBHelper::get_class_nmdb($host, $username, $password);57 $connector -> select_db($database);58 ?>
复制代码

也可以参考这个类实现:

复制代码
 1 <?php 2 /* 3 * mysql 单例 4 */ 5 class mysql{ 6     private $host    ='localhost'; //数据库主机 7     private $user     = 'root'; //数据库用户名 8     private $pwd     = ''; //数据库用户名密码 9     private $database = 'imoro_imoro'; //数据库名10     private $charset = 'utf8'; //数据库编码,GBK,UTF8,gb231211     private $link;             //数据库连接标识;12     private $rows;             //查询获取的多行数组13     static $_instance; //存储对象14     /**15      * 构造函数16      * 私有17      */18     private function __construct($pconnect = false) {19         if (!$pconnect) {20             $this->link = @ mysql_connect($this->host, $this->user, $this->pwd) or $this->err();21         } else {22             $this->link = @ mysql_pconnect($this->host, $this->user, $this->pwd) or $this->err();23         }24         mysql_select_db($this->database) or $this->err();25         $this->query("SET NAMES '{$this->charset}'", $this->link);26         return $this->link;27     }28     /**29      * 防止被克隆30      *31      */32     private function __clone(){}33     public static function getInstance($pconnect = false){34         if(FALSE == (self::$_instance instanceof self)){35             self::$_instance = new self($pconnect);36         }37         return self::$_instance;38     }39     /**40      * 查询41      */42     public function query($sql, $link = '') {43         $this->result = mysql_query($sql, $this->link) or $this->err($sql);44         return $this->result;45     }46     /**47      * 单行记录48      */49     public function getRow($sql, $type = MYSQL_ASSOC) {50         $result = $this->query($sql);51         return @ mysql_fetch_array($result, $type);52     }53     /**54      * 多行记录55      */56     public function getRows($sql, $type = MYSQL_ASSOC) {57         $result = $this->query($sql);58         while ($row = @ mysql_fetch_array($result, $type)) {59             $this->rows[] = $row;60         }61         return $this->rows;62     }63     /**64      * 错误信息输出65      */66     protected function err($sql = null) {67         //这里输出错误信息68         echo 'error';69         exit();70     }71 }72 //用例73 $db = mysql::getInstance();74 $db2 = mysql::getInstance();75 $data = $db->getRows('select * from blog');76 //print_r($data);77 //判断两个对象是否相等78 if($db === $db2){79     echo 'true';80 }81 ?>