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单例模式我觉得只是针对单次页面级请求时出现多个应用场景并需要共享同一对象资源时是非常有意义的。
数据库交互
一个应用中会存在大量的数据库操作,比如过数据库句柄来连接数据库这一行为,使用单例模式可以避免大量的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(...);
- ?>
- <?php
- class db {
- public $conn;
- public static $sql;
- public static $instance=null;
- private function __construct(){
- require_once('db.config.php');
- $this->conn = mysql_connect($db['host'],$db['user'],$db['password']);
- if(!mysql_select_db($db['database'],$this->conn)){
- echo "失败";
- };
- mysql_query('set names utf8',$this->conn);
- }
- public static function getInstance(){
- if(is_null(self::$instance)){
- self::$instance = new db;
- }
- return self::$instance;
- }
- /**
- * 查询数据库
- */
- public function select($table,$condition=array(),$field = array()){
- $where='';
- if(!empty($condition)){
- foreach($condition as $k=>$v){
- $where.=$k."='".$v."' and ";
- }
- $where='where '.$where .'1=1';
- }
- $fieldstr = '';
- if(!empty($field)){
- foreach($field as $k=>$v){
- $fieldstr.= $v.',';
- }
- $fieldstr = rtrim($fieldstr,',');
- }else{
- $fieldstr = '*';
- }
- self::$sql = "select {$fieldstr} from {$table} {$where}";
- $result=mysql_query(self::$sql,$this->conn);
- $resuleRow = array();
- $i = 0;
- while($row=mysql_fetch_assoc($result)){
- foreach($row as $k=>$v){
- $resuleRow[$i][$k] = $v;
- }
- $i++;
- }
- return $resuleRow;
- }
- /**
- * 添加一条记录
- */
- public function insert($table,$data){
- $values = '';
- $datas = '';
- foreach($data as $k=>$v){
- $values.=$k.',';
- $datas.="'$v'".',';
- }
- $values = rtrim($values,',');
- $datas = rtrim($datas,',');
- self::$sql = "INSERT INTO {$table} ({$values}) VALUES ({$datas})";
- if(mysql_query(self::$sql)){
- return mysql_insert_id();
- }else{
- return false;
- };
- }
- /**
- * 修改一条记录
- */
- public function update($table,$data,$condition=array()){
- $where='';
- if(!empty($condition)){
- foreach($condition as $k=>$v){
- $where.=$k."='".$v."' and ";
- }
- $where='where '.$where .'1=1';
- }
- $updatastr = '';
- if(!empty($data)){
- foreach($data as $k=>$v){
- $updatastr.= $k."='".$v."',";
- }
- $updatastr = 'set '.rtrim($updatastr,',');
- }
- self::$sql = "update {$table} {$updatastr} {$where}";
- return mysql_query(self::$sql);
- }
- /**
- * 删除记录
- */
- public function delete($table,$condition){
- $where='';
- if(!empty($condition)){
- foreach($condition as $k=>$v){
- $where.=$k."='".$v."' and ";
- }
- $where='where '.$where .'1=1';
- }
- self::$sql = "delete from {$table} {$where}";
- return mysql_query(self::$sql);
- }
- public static function getLastSql(){
- echo self::$sql;
- }
- }
- $db = db::getInstance();
- //$list = $db->select('demo',array('name'=>'tom','password'=>'ds'),array('name','password'));
- //echo $db->insert('demo',array('name'=>'最近你啦','password'=>'123'));
- //echo $db->update('demo',array("name"=>'xxx',"password"=>'123'),array('id'=>1));
- echo $db->delete('demo',array('id'=>'2'));
- db::getLastSql();
- echo "<pre>";
- ?>
PHP 单例模式解析和实战的更多相关文章
- 学习TF:《TensorFlow技术解析与实战》PDF+代码
TensorFlow 是谷歌公司开发的深度学习框架,也是目前深度学习的主流框架之一.<TensorFlow技术解析与实战>从深度学习的基础讲起,深入TensorFlow框架原理.模型构建. ...
- Elasticsearch技术解析与实战 PDF (内含目录)
Elasticsearch技术解析与实战 介绍: Elasticsearch是一个强[0大0]的搜索引擎,提供了近实时的索引.搜索.分 ...
- Web安全测试中常见逻辑漏洞解析(实战篇)
Web安全测试中常见逻辑漏洞解析(实战篇) 简要: 越权漏洞是比较常见的漏洞类型,越权漏洞可以理解为,一个正常的用户A通常只能够对自己的一些信息进行增删改查,但是由于程序员的一时疏忽,对信息进行增删改 ...
- elasticsearch技术解析与实战ES
elasticsearch技术解析与实战ES 下载地址: https://pan.baidu.com/s/1NpPX05C0xKx_w9gBYaMJ5w 扫码下面二维码关注公众号回复100008 获取 ...
- Docker小白到实战之Dockerfile解析及实战演示,果然顺手
前言 使用第三方镜像肯定不是学习Docker的最终目的,最想要的还是自己构建镜像:将自己的程序.文件.环境等构建成自己想要的应用镜像,方便后续部署.启动和维护:而Dockerfile就是专门做这个事的 ...
- 《Android源代码设计模式解析与实战》读书笔记(十七)
第十七章.中介者模式 中介者模式也称为调解者模式或调停者模式,是一种行为型模式. 1.定义 中介者模式包装了一系列对象相互作用的方式.使得这些对象不必相互明显作用.从而使它们能够松散耦合.当某些对象之 ...
- 《Android源代码设计模式解析与实战》读书笔记(十)
第十章.解释器模式 解释器模式是一种用的比較少的行为型模式.其提供了一种解释语言的语法或表达式的方式. 可是它的使用场景确实非常广泛,仅仅是由于我们自己非常少回去构造一个语言的文法,所以使用较少. 1 ...
- Java日志框架解析及实战分析
转载自: https://zhuanlan.zhihu.com/p/24272450 https://zhuanlan.zhihu.com/p/24275518 作为Java程序员,幸运的是,Java ...
- 深入解析Vuex实战总结
这篇文章主要介绍了Vuex的初探与实战小结,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. 1.背景 最近在做一个单页面的管理后台项目,为了提高开 ...
随机推荐
- 201521123032 《Java程序设计》第6周学习总结
1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2. 书面作业 1. clone方法 1.1 Object ...
- 201521123100 《Java程序设计》第5周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 1.接口不是类,不能使用new进行实例化 2.使用instanceof运算符,可 ...
- 201521123018 《Java程序设计》第4周学习总结
1. 本章学习总结 2. 书面作业 Q1.注释的应用:使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看.(截图) Q2.面向对象设计(大作业1-非常重要) 2.1 讲故事 ...
- 201521123032 《Java程序设计》第11周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...
- 一步步带你做vue后台管理框架(三)——登录功能
系列教程<一步步带你做vue后台管理框架>第三课 github地址:vue-framework-wz 线上体验地址:立即体验 <一步步带你做vue后台管理框架>第一课:介绍框架 ...
- Servlet第三篇【request和response简介、response的常见应用】
response.request对象 Tomcat收到客户端的http请求,会针对每一次请求,分别创建一个代表请求的request对象.和代表响应的response对象 既然request对象代表ht ...
- js 第一课
什么是JavaScript JavaScript是一种脚本语言,运行在网页上.无需安装编译器.只要在网页浏览器上就能运行 一般JavaScript与HTML合作使用. 例如 <html> ...
- DI in ASP.NET Core
.NET-Core Series Server in ASP.NET-Core DI in ASP.NET-Core Routing in ASP.NET-Core Error Handling in ...
- 微信bug:建议了解,不要实验,不要手贱,不要。。。。
今天下午在群里聊天的时候,群友反应发现微信的一个bug:使用微信给好友发送‘15...............’(数字15后面加15个句号)会导致微信运行缓慢,到最后的应用未响应,退出微信. 解决办法 ...
- HTTP协议报文、工作原理
一.web及网络基础 1.HTTP的历史 1.1.HTTP的概念: HTTP(Hyper Text Transfer Protocol ...