热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP单例模式实例浅析

全局变量是面向对象程序员遇到的引发bug的主要原因之一,这是因为全局变量将类捆绑于特定的环境,破坏了封装,如果新的应用程序无法保证一开始就定义了相同的环境变量,那么一个依赖于全局变

全局变量是面向对象程序员遇到的引发bug的主要原因之一,这是因为全局变量将类捆绑于特定的环境,破坏了封装,如果新的应用程序无法保证一开始就定义了相同的环境变量,那么一个依赖于全局变量的类就无法从一个应用程序中提取出来并应用到新的应用程序中.

什么是单例模式呢

单例模式顾名思义,就是只有一个实例,作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类我们称之为单例类。

单例模式的要点有三个:

它们必须拥有一个构造函数,并且必须被标记为private,它们拥有一个保存类的实例的静态成员变量,它们拥有一个访问这个实例的公共的静态方法,和普通类不同的是,单例类不能在其他类中直接实例化,单例类只能被其自身实例化,要获得这样的一种结果,__construct()方法必须被标记为private,如果试图用private构造函数构造一个类,就会得到一个可访问性级别的错误.

要让单例类起作用,就必须使其为其他类提供一个实例,用它调用各种方法,单例类不会创建实例副本,而是会向单例类内部存储的实例返回一个引用,结果是单例类不会重复占用内存和系统资源,从而让应用程序的其它部分更好地使用这些资源,作为这一模式的一部分,必须创建一个空的私有__clone()方法,以防止对象被复制或克隆.

返回实例引用的这个方法通常被命名为getInstance(),这个方法必须是静态的,而且如果它还没有实例化,就必须进行实例化,getInstance() 方法通过使用 instanceof 操作符和self 关键字,可以检测到类是否已经被实例化,代码如下:

header("Content-type:text/html;charset=utf-8"); 
	//单例测试类 
	class Test { 
	    private $unique; 
	    static private $instance;//静态属性保存该类实例 
	       
	    private function __construct(){//构造方法私有(防止外界调用) 
	        $this->unique=rand(0,20000); 
	    } 
	    static public function getInstance(){//静态方法提供对外接口(获取实例) 
	        if(!self::$instance instanceof self){ 
	            self::$instance=new self(); 
	        } 
	        return self::$instance; 
	    } 
	    private function __clone(){}//私有克隆方法,防止外界直接克隆该实例 
	      
	} 
	$test=Test::getInstance(); 
	$test2=Test::getInstance(); 
	  
	print_r($test);  
	print_r($test2); 
	      
	if($test===$test2){ 
	    echo '相等!'; 
	}else{ 
	    echo '不相等!'; 
	}

好了,该说书代码了,我们在程序中查询数据的操作会非常非常的多,我们不可能每次都new一个对象,这样太耗费开销了,那么我们怎么办呢,单例模式是个不错的选择,单例模式,只能实例化一次,下面看一下代码.

db.class.php,代码如下:

conn = mysql_connect($db['host'], $db['user'], $db['psd']);
        if (!mysql_select_db($db['databases'], $this->conn)) {
            echo "数据库连接错误";
        }
        mysql_query('set names utf8', $this->conn);
    }
    public static function getInstance() {
        if (is_null(self::$instact)) {
            self::$instact = new db;
        }
        return self::$instact;
    }
    /** 
     *数据查询
     */
    public function select($table, $condition = array() , $field = array()) {
        $where = "";
        if (!emptyempty($condition)) {
            foreach ($condition as $k => $v) {
                $where.= $k . "='" . $v . "' and ";
            }
            $where = "where " . $where . " 1=1";
        }
        if (!emptyempty($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);
        $i = 0;
        while ($row = mysql_fetch_assoc($result)) {
            foreach ($row as $k => $v) {
                $resultrow[$i][$k] = $v;
            }
            $i++;
        }
        var_dump($resultrow);
    }
    /** 
     *数据添加
     */
    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 (!emptyempty($condition)) {
            foreach ($condition as $k => $v) {
                $where.= $k . "=" . $v . " and ";
            }
            $where = "where " . $where . "1=1";
        }
        $updatastr = "";
        if (!emptyempty($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 (!emptyempty($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);
    }
    //打印sql
    public function getlastsql() {
        echo self::$sql;
    }
}
$ne = db::getInstance();
//$ne->update('message',array('user'=>'wanghao','title'=>'sd'),array('id'=>'5'));
//echo $db->insert('message',array('user'=>'张三','title'=>'demo'));
$ne->select('message', array(
    'user' => 'songlin'
));
$ne->getlastsql();

数据库的配置文件,db.config.php:

$host, 
	"user" =>$user, 
	"psd" =>$psd, 
	"databases"=>$databases 
	); 	



推荐阅读
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • PHP中的单例模式与静态变量的区别及使用方法
    本文介绍了PHP中的单例模式与静态变量的区别及使用方法。在PHP中,静态变量的存活周期仅仅是每次PHP的会话周期,与Java、C++不同。静态变量在PHP中的作用域仅限于当前文件内,在函数或类中可以传递变量。本文还通过示例代码解释了静态变量在函数和类中的使用方法,并说明了静态变量的生命周期与结构体的生命周期相关联。同时,本文还介绍了静态变量在类中的使用方法,并通过示例代码展示了如何在类中使用静态变量。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
author-avatar
老娘叫凌凌_523
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有