打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
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);

执行结果:

 

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

  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_BOTH100     */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 //切换数据库hkxy156 $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);

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

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

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

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

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
php分页代码简单实现
任务11 PHP程序开发范例
PHP以mysqli方式连接类完整代码实例
【Go语言】连接数据库SQLite、MySQL、Oracle
Python使用win32com模块实现数据库表结构自动生成word表格的方法
浅谈网络客户端的类库编写和使用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服