php 单例模式

使用场景:数据库连接

首先,将该类的构造函数私有化(目的是禁止其他程序创建该类的对象);
其次,在本类中自定义一个对象(既然禁止其他程序创建该类的对象,就要自己创建一个供程序使用,否则类就没法用,更不是单例);
最后,提供一个可访问类自定义对象的类成员方法(对外提供该对象的访问方式)。
直白的讲就是,你不能用该类在其他地方创建对象,而是通过该类自身提供的方法访问类中的那个自定义对象。
那么问题的关键来了,程序调用类中方法只有两种方式,①创建类的一个对象,用该对象去调用类中方法;②使用类名直接调用类中方法,格式“类名.方法名()”;
上面说了,构造函数私有化后第一种情况就不能用,只能使用第二种方法。
而使用类名直接调用类中方法,类中方法必须是静态的,而静态方法不能访问非静态成员变量,因此类自定义的实例变量也必须是静态的。
这就是单例模式唯一实例必须设置为静态的原因。

单例模式连接数据库

三私一公:私有化静态属性,私有化构造方法,私有化克隆方法,公有化静态方法。

一个单例类应具备以下特点:

单例类不能直接实例化创建,而是只能由类本身实例化。因此,要获得这样的限制效果,构造函数必须标记为private,从而防止类被实例化。

需要一个私有静态成员变量来保存类实例和公开一个能访问到实例的公开静态方法。

在PHP中,为了防止他人对单例类实例克隆,通常还为其提供一个空的私有__clone()方法。

使用场景:只实例化一次,内部实例化,对外只有一个开放方法,只能通过调取该方法进行调取实例化对象。数据库连接

<?php
定义常量 define("DB_HOST", "127.0.0.1"); define("DB_USER", "root"); define("DB_PASSWORD", "root"); define("DB_DBNAME", "dml"); class db {
定义静态变量d,存储实例的对象 private static $d;
定义变量db存储数据库对象 protected $db;
protected $host; protected $user; protected $pwd; protected $dbname; private function __construct($host=DB_HOST,$user=DB_USER,$pwd=DB_PASSWORD,$dbname=DB_DBNAME) { $this->host=$host; $this->user=$user; $this->pwd=$pwd; $this->dbname=$dbname;
执行数据库连接的操作 if (!$this->db) { $this->conn(); } }
数据库连接的方法 private function conn() { $conn=new mysqli($this->host,$this->user,$this->pwd); if($conn->connect_error){ echo "数据库连接失败,错误信息:" . $conn->connect_error; }
连接数据库 $conn->select_db($this->dbname);
设置字符集 $conn->set_charset("utf8"); $this->db=$conn; } 禁止克隆 private function __clone() { }
实例化类操作 public static function getdb() {
判断变量d是否是这个类本身实例化的对象 if (!self::$d instanceof self) { self::$d = new self; } return self::$d; } 数据库增删改查操作 public function querydb($sql) { $res = $this->db->query($sql)->fetch_all(MYSQLI_ASSOC); return $res; } } 调用时,先调用实例化类的方法 $aa=db::getdb(); $res=$aa->querydb("SELECT * FROM `user`"); var_dump($res);

例子(1)
<?php
class db{
private static $conn;

//禁止其它地方实例化
private function __construct(){}
//禁止克隆
private function __colone(){}

//由于构造方法定义为private不能使用new来实例化,所以方法只能也用static,又由于静态方法不能用$this->conn所以属性也静态化了
public static function gettest(){
if(empty(self::$conn)){
self::$conn = new db;
}
return self::$conn;
}

public static function test(){
return new db;
}


}

$test1 = db::gettest();
$test2 = db::test(); //实例化第二次
$test3 = db::gettest();

var_dump($test1,$test2,$test3);
//object(db)#1 (0) { } object(db)#2 (0) { } object(db)#1 (0) { }
exit;
posted @ 2020-07-30 22:41  快乐的在一起  阅读(169)  评论(0编辑  收藏  举报