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.背景 最近在做一个单页面的管理后台项目,为了提高开 ...
随机推荐
- Java课程设计-学生基本信息管理 201521123036
团队课程设计博客链接 团队博客链接 个人负责模块或任务说明 个人负责模块 任务说明 用户登录,注册 登录,注册,判断用户是否存在,添加用户 学生信息管理菜单 按钮,跳转相应界面,退出程序 学生信息添加 ...
- 201521123033《Java程序设计》第12周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...
- 201521123052 《Java程序设计》 第14周学习总结
1. 本周学习总结 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自己的学号.姓名) 在自己建立的数据库上执行常见SQL语句(截图) - ...
- 201521123051《Java程序设计》第十二周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 一 JAVA语言中主要通过流来完成IO操作. 流:计算机的输入输出之间流动的数据序列,也是类的对象.java中 ...
- 解决liblzo2.so缺失
系统:CentOS5.8 提示错误: error while loading shared libraries: liblzo2.so.2: cannot open shared object fil ...
- C#设计模式之二简单工厂模式(过渡模式)
一.引言 之所以写这个系列,是了为了自己更好的理解设计模式,也为新手提供一些帮助,我都是用最简单的.最生活化的实例来说明.在上一篇文章中讲解了单例模式,今天就给大家讲一个比较简单的模式--简单工厂模式 ...
- Mysql免安装版配置【图文版和文字版】
图文版 配置环境变量 新建一个my.ini文件,添加下面内容 [mysqld] basedir=C:\\software\Mysql\mysql-5.7.14-winx64 datadir=C:\\s ...
- Java http请求和调用
关于http get和post请求调用代码以及示例. 参考:http://www.cnblogs.com/zhuawang/archive/2012/12/08/2809380.html http请求 ...
- C#中的两把双刃剑:抽象类和接口
问题出现: 这也是我在学习抽象类和接口的时候遇到的问题,从我归纳的这三个问题,不难看出这也许是我们大多数程序员遇到问题的三个阶段, 第一阶段(基础概念):就象问题1一样,这部分人首先需要扫清基础概念的 ...
- ng-transclude
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...