单例模式也就是一个类只能创建出一个对象
首先你要知道它的基本思想为:三私一公
何为三私一公?
 
1(私)、防止用户通过构造方法创建对象,因此私有化构造方法。
2(公)、创建一个公共静态函数用来进入类内部;思考:为什么要是静态的?为什么要公开?答:因为目前没有任何对象,只能由类来调用;因为需要类外调用
3(私)、增加一个静态私有属性:该静态属性用于保存已经实例化好了的对象,判断是否存在这个对象,如果存在,后续调用的时候直接返回它就行了!思考:为什么要是静态的?为什么要私有?答:因为还没有对象,只能用类去访问;因为要保证类外不能操作该属性。
4(私)、将克隆方法私有化,防止用户通过克隆来创建新的对象。
以下通过一个数据库连接的例子来讲解:
<?php
class MySQLDB{
//定义数据可连接和要用到的属性
private $host;//主机地址
private $port;//端口号
private $user;//用户名
private $pass;//密码
private $charset;//默认字符集
private $dbname;//默认数据库
private $link;//保存连接资源
private static $instance;//定义一个私有化静态变量用来判断是否为新对象
//私有化构造函数
private function __construct($config){
$this->init($config);//调用初始化属性的值函数
$this->my_connect();//调用连接数据库函数
$this->my_charset();//调用设置字符集函数
$this->my_dbname();//设置数据库 }
//初始化私有属性的值
private function init($config){
$this->host=$config['host']?? "localhost";//判断用户是否传入了host这个属性,有的话就使用用户传入的否则就使用默认属性。??这个是简化版的三目运算符。
$this->port=$config['port']?? 3306;//下面这些都是和上面一样
$this->user=$config['user']?? 'root';
$this->pass=$config['pass']?? 'admain';
$this->charset=$config['charset']?? 'utf8';
$this->dbname=$config['dbname']?? 'php';
}
//获得实例化对象
public static function instance($config){
if(!self::$instance instanceof self){ //判断是否这个私有化静态变量是一个对象,不是就创建一个对象。
self::$instance=new self($config);
}
return self::$instance; //返回这个私有化静态变量 }
//定义私有化克隆防止克隆出一个新的对象
private function __clone(){ }
//连接数据库
private function my_connect(){
$link=mysqli_connect("$this->host:$this->port",$this->user,$this->pass);//连接数据库并把值赋给$link.注意这个$link和最开始定义的那个私有化属性$link不一样,只是恰好名字一样而已
if($link){ //判断是否存在这个$link.因为$link是个资源集所以可以直接判断
$this->link=$link;//存在则把这个$link资源集赋值给私有化属性$link
}else{
echo "对不起连接数据库失败";
return false;
}
}
//封装判断函数
private function my_query($sql){
$res=mysqli_query($this->link,$sql);
if(!$res){
echo "对不起语句执行失败";
return false;
}else{
return $res;
}
}
//选择字符集
private function my_charset(){
$sql="set names $this->charset";
$this->my_query($sql);
}
//选择数据库
private function my_dbname(){
$sql="use $this->dbname";
$this->my_query($sql);
}
//释放资源
private function __destruct(){
@mysqli_close($this->link);
} }
$config=array("user"=>"root","pass"=>"admain");//定义要传入的数组参数
$obj= MySQLDB::instance($config);//调用公共静态函数来创建一个对象
$obj1= MySQLDB::instance($config);//这里再次调用用来验证是否只能出创建一个对象。
var_dump($obj);
var_dump($obj1);
结果我这里就不放出来了图片有点大。你会发现var_dump()出来的这两个对象一模一样。

php通过单例模式使一个类只能创建一个对象。的更多相关文章

  1. python 单例模式,一个类只能生成唯一的一个实例,重写__new__方法详解

    单例:一个类只能生成唯一的一个实例 每个类只要被实例化了,他的私有属性 '_instance'就会被赋值,这样理解对吗 对 #方法1,实现__new__方法 #并在将一个类的实例绑定到类变量_inst ...

  2. java_实现一个类只能声明一个对象

    public class StaticDemo { public int a=10; private static StaticDemo s= new StaticDemo(); private St ...

  3. singleton 类模板限制类只能定义一个对象

    singleton 类模板限制类只能定义一个对象 singleton 类模板限制类只能定义一个对象 singleton 类模板限制类只能定义一个对象 ???

  4. C++中如何设计一个类只能在堆或者栈上创建对象,面试题

    设计一个类,该类只能在堆上创建对象 将类的构造函数私有,拷贝构造声明成私有.防止别人调用拷贝在栈上生成对象. 提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建 注意 在堆和栈上创建对象都会调 ...

  5. java单例模式(类只能创建唯一对象)

    //饿汉式 class Single { private static final Single s= new Single(); private Single(){} public static S ...

  6. 10.按要求编写Java应用程序。 (1)创建一个叫做People的类: 属性:姓名、年龄、性别、身高 行为:说话、计算加法、改名 编写能为所有属性赋值的构造方法; (2)创建主类: 创建一个对象:名叫“张三”,性别“男”,年龄18岁,身高1.80; 让该对象调用成员方法: 说出“你好!” 计算23+45的值 将名字改为“李四”

    package com.hanqi.test; public class People { private String name,sex; private int age; private doub ...

  7. 按要求编写Java应用程序。 (1)创建一个叫做People的类: 属性:姓名、年龄、性别、身高 行为:说话、计算加法、改名 编写能为所有属性赋值的构造方法; (2)创建主类: 创建一个对象:名叫“张三”,性别“男”,年龄18岁,身高1.80; 让该对象调用成员方法: 说出“你好!” 计算23+45的值 将名字改为“李四”

    package java1; public class People { public String name; public int age; public String sex; public S ...

  8. 创建一个叫做People的类: 属性:姓名、年龄、性别、身高 行为:说话、计算加法、改名 编写能为所有属性赋值的构造方法; (2)创建主类: 创建一个对象:名叫“张三”,性别“男”,年龄18岁,身高1.80; 让该对象调用成员方法: 说出“你好!” 计算23+45的值 将名字改为“李四”

    package com.chuoji; public class People { private String name; private int age; private String sex; ...

  9. (1)创建一个叫做People的类: 属性:姓名、年龄、性别、身高 行为:说话、计算加法、改名 编写能为所有属性赋值的构造方法; (2)创建主类: 创建一个对象:名叫“张三”,性别“男”,年龄18岁,身高1.80; 让该对象调用成员方法: 说出“你好!” 计算23+45的值 将名字改为“李四”

    package a; public class People { private String name,sex; private int age; private double height; pu ...

随机推荐

  1. StringTokenizer(字符串分隔解析类型)

    java.util.StringTokenizer 功效:将字符串以定界符为界,分析为一个个的token(可理解为单词),定界符可以自己指定.  1.构造函数. 1. StringTokenizer( ...

  2. python3下scrapy爬虫(第五卷:初步抓取网页内容之scrapy全面应用)

    现在爬取http://category.dangdang.com/pg1-cid4008149.html网址上的商品价格,名称,评价数量 先准备下下数据:商品名,商品链接,评价数量 第一步:在item ...

  3. MyBatis延迟加载及缓存

    延迟加载 lazyLoadingEnabled 定义: MyBatis中的延迟加载也成为懒加载,就是在进行关联查询的时候按照设置延迟加载规则推迟对关联对象的select检索.延迟加载可以有效的减少数据 ...

  4. the extent of|fill in|find itimpossible to|something|the other day|Be man enough to do sth/for sth|cure sb of |draw out| gone over|made for | see someone off,|

    area or length; amount 面积,范围:长度:数量 We don't yet know the extent of his injuries (= how bad his injur ...

  5. idea常见需求

    1.给class加注释模板 /** *@ClassName ${NAME} *@Description TODO *@Author xxx *@Date ${DATE} ${TIME} *@Versi ...

  6. mongodb配置windows服务启动

    第一步 下载MongoDB http://www.mongodb.org/downloads 第二步 解压到D:\mongodb\目录下,为了命令行的方便,可以把D:\mongodb\bin加到系统环 ...

  7. Spring Security基本原理

    近期研究了Spring Security,现进行记录. 首先先进行一个最简单的demo.默认情况下,在Spring Boot里,如果在classpath下面有Spring Security相关的jar ...

  8. SpringMVC之添加照片并修改照片名字

    @RequestMapping(value="/addIdcardsSubmit",method={RequestMethod.POST,RequestMethod.GET}) p ...

  9. Python---9高级特性

    一.切片 取一个list或tuple的部分元素是非常常见的操作.比如,一个list如下: >>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', ' ...

  10. numpy学习总结

    Contents Numpy是一个用python实现的科学计算包,主要提供矩阵运算的功能,而矩阵运算在机器学习领域应用非常广泛,Numpy一般与Scrapy.matplotlib一起使用. Numpy ...