zoukankan      html  css  js  c++  java
  • PHP设计模式-单例模式

    一直以来都是在写项目却从来没有仔细分析过什么是单例模式,单例模式分为几种,单例模式有什么特点。今天随便记录一个随笔,全当是复习复习做个笔记。

    单例模式要确保某个类只有一个实例,而且自动实例化并向整个系统提供实例。单例模式分为3种:饿汉单例模式、懒汉单例模式、登记式单例模式。

    单例模式有3个特点:

    1. 只有一个实例
    2. 必须自行创建这个实例
    3. 必须给其他对象提供这个实例

    单例模式常被应用到数据库连接,这种耗费资源的操作。类的结构分为3私1公/4私1公。下面就编写一个简单的单例模式:

     1 <?php
     2 
     3 class db {
     4 
     5     private $config = 1;
     6 
     7     //私有的静态变量,默认值为null
     8     private static $instance = null;
     9 
    10     /**
    11     * 私有构造方法
    12     * 防止多个实例
    13     */
    14     private function __construct($config) {
    15         echo '我是私有构造方法<br>';
    16     }
    17 
    18     /**
    19     * 私有克隆方法 
    20     * 防止多个实例
    21     */
    22     private function __clone() {
    23 
    24     }
    25 
    26     /**
    27     * 防止反序列化
    28     */
    29     private function __wakeup() {
    30 
    31     }
    32 
    33     /**
    34     * 公有静态方法
    35     * 判断$instance是否实例化,存在实例化对象就直接返回,不存在实例化对象就new实例化
    36     */
    37     public static function getInstance() {
    38         if(is_null(self::$instance)) {
    39             self::$instance = new self();
    40         }
    41         return self::$instance;
    42     }
    43 }
    44 
    45 $db = db::getInstance();
    46 var_dump($db);
    47 $db = db::getInstance();
    48 var_dump($db);

    执行结果:

    MySQL连接单例模式

    可以看到两次执行的句柄都一样是同一个实例。接下来把这个单例完善一下变成一个数据库连接的单例模式:

      1 <?php
      2 
      3 class db {
      4 
      5     //私有link变量
      6     private $link;
      7 
      8     private $config = [
      9         'host' => 'localhost',
     10         'username' => 'root',
     11         'password' => 'root',
     12         'databases' => '',
     13         'port' => 3306,
     14         'conding' => 'utf8'
     15     ];
     16 
     17 
     18     //私有的静态变量,默认值为null
     19     private static $instance = null;
     20 
     21     /**
     22     * 私有构造方法
     23     * 防止多个实例
     24     * array $config 数据库配置
     25     */
     26     private function __construct($config) {
     27         //判断$config配置是否设置,并且是数组
     28         if(isset($config) && is_array($config)) {
     29             //存在配置,和默认配置合并,用新的配置替换默认配置
     30             $this->config = array_merge($this->config, $config);
     31         }
     32         //创建数据库连接
     33         $this->link = mysqli_connect($this->config['host'], $this->config['username'], $this->config['password'], $this->config['databases'], $this->config['port']);
     34 
     35         //输出连接错误
     36         $this->connect_errno();
     37 
     38         if($this->config['databases']) {
     39             $conding = $this->config['conding'];
     40             $this->query("SET NAMES '{$condig}'");
     41         }
     42         
     43         return $this->link;
     44     }
     45 
     46     /**
     47     * 私有克隆方法 
     48     * 防止多个实例
     49     */
     50     private function __clone() {
     51 
     52     }
     53 
     54     /**
     55     * 防止反序列化
     56     */
     57     private function __wakeup() {
     58 
     59     }
     60 
     61     /**
     62     * 公有静态方法
     63     * 判断$instance是否实例化,存在实例化对象就直接返回,不存在实例化对象就new实例化
     64     * array $config 数据库配置
     65     */
     66     public static function getInstance($config) {
     67         //判断变量$instance是否存在实例化对象,不存在
     68         if(is_null(self::$instance)) {
     69             //自动实例化,给构建方法传$config配置
     70             self::$instance = new self($config);
     71         }
     72         //返回$instance实例化对象
     73         return self::$instance;
     74     }
     75 
     76     /**
     77     * 执行sql
     78     * $query sql语句
     79     */
     80     public function query($query) {
     81         $this->result = mysqli_query($this->link, $query);
     82         return $this->result;
     83     }
     84 
     85     /**
     86     * 选择数据库
     87     * string $dbname 数据库名称
     88     */
     89     public function select_db($dbname) {
     90         $this->result = mysqli_select_db($this->link, $dbname);
     91         $conding = $this->config['conding'];
     92         $this->query("SET NAMES '{$condig}'");
     93         return $this->result;
     94     }
     95 
     96     /**
     97     * 查询一条或多条数据
     98     * string $sql sql语句
     99     * MYSQLI_NUM、MYSQLI_ASSOC、MYSQLI_BOTH
    100     */
    101     public function fetch_array($sql, $type = MYSQLI_BOTH) {
    102         $result = $this->query($sql);
    103         $rows = mysqli_fetch_array($result, $type);
    104         if($this->num_rows($result) > 1) {
    105             while($rows) {
    106                 $this->rows[] = $rows;
    107             }
    108         } else {
    109             $this->rows = $rows;
    110         }
    111         return $this->rows;
    112     }
    113 
    114     public function num_rows($result) {
    115         $this->result = mysqli_num_rows($result);
    116         return $this->result;
    117     }
    118 
    119     /**
    120     * 输出连接错误
    121     */
    122     private function connect_errno() {
    123         if(mysqli_connect_errno($this->link)) {
    124             echo 'MySQL数据库连接失败,错误代码ERROR:' . mysqli_connect_errno() . '<br>';
    125         }
    126     }
    127 
    128     /**
    129     * 关闭数据库连接
    130     */
    131     public function close() {
    132         $this->result = mysqli_close($this->link);
    133         return $this->result;
    134     }
    135 
    136 
    137 }
    138 
    139 $config = [
    140     'host' => '172.17.0.2',
    141     'username' => 'root',
    142     'password' => 'cuiyuanxin66666',
    143     // 'databases' => 'nndb'
    144 ];
    145 $db = db::getInstance($config);
    146 $db1 = db::getInstance($config);
    147 //判断两个实例对象是否一致
    148 if($db === $db1) {
    149     echo '一致';
    150     echo '<br>';
    151 } else {
    152     echo '不一致';
    153     echo '<br>';
    154 }
    155 //切换数据库hkxy
    156 $db->select_db('hkxy');
    157 $sql = 'select * from qii_admin_menu limit 1';
    158 $rows = $db->fetch_array($sql, MYSQLI_ASSOC);
    159 var_dump($db);
    160 echo '<br>-----------------------------------------<br>';
    161 var_dump($rows);
    162 echo '<br>-----------------------------------------<br>';
    163 $db->select_db('nndb');
    164 $sql = 'select * from niuniu_user limit 1';
    165 $rows = $db->fetch_array($sql, MYSQLI_ASSOC);
    166 var_dump($rows);

    经过改造一个连接数据库的单例模式就写完了,看一下执行结果:

    MySQL连接单例模式

    通过代码来看两个实例对象完全一样。

    源代码已上传GitHub:https://github.com/cuiyuanxin/php-demo/blob/master/db.php

    纯手打笔记,如有错误请评论提出,谢谢。

  • 相关阅读:
    结构体中的冒号_转
    随机数产生random
    gdb调试段错误及使用
    gcc选项-g与-rdynamic的异同_转
    linux设备模型_转
    boost 1.57.0安装
    技术的正宗与野路子_转
    (转)Java里的堆(heap)栈(stack)和方法区(method)(精华帖,多读读)
    (转)面试大总结之一:Java搞定面试中的链表题目
    (转)类加载器与双亲委派模型
  • 原文地址:https://www.cnblogs.com/cuiyuanxin/p/10421440.html
Copyright © 2011-2022 走看看