一、单例描述
前两天面试微博让写一个单例出来,我愣是没写出去,作为一个三年的PHP程序员说出去有点丢人,所以下来赶紧学习了一下。
首先要明白为什么要单例?所谓单例就是说用 无论多少个用户访问,过来只实例一个对象,这样就会节省内存,实现一个对象大家共同调用。其中最为经典的就是数据库对象了,因为我们连接数据库的时候一般是同一个用户名密码的。
二、单例基本思想代码实现
对于PHP而言,单例就是三私一公,所谓三私一公指的是私有的构造方法,私有的克隆方法 ,私有的静态属性,公共的静态方法。
下面看代码
<?php
//防止用户继承
final Class Db
{
//私有的静态属性,用来存唯一的对象
private static $db = NULL;
//私有的构造方法,防止用户New对象
private function __construct()
{
}
//私有的克隆方法,防止用户克隆对象
private function __clone()
{
}
//公共的静态方法
public static function getDbInstance()
{
if (!self::$db instanceof self) {
self::$db = new self();
}
return self::$db;
}
}
//可以打印看下是不是一个对象
$db1 = Db::getDbInstance();
$db2 = Db::getDbInstance();
var_dump($db1,$db2);
三、单例实现数据库操作类
<?php
//防止用户继承
final Class Db
{
//私有的静态属性,用来存唯一的对象
private static $db = NULL;
private static $mysql = NULL;
//私有的配置信息
private $db_host;
private $db_user;
private $db_pass;
private $db_name;
//私有的构造方法,防止用户New对象
private function __construct(array $config)
{
$this->db_host = $config['db_host'];
$this->db_user = $config['db_user'];
$this->db_pass = $config['db_pass'];
$this->db_name = $config['db_name'];
//连接mysql
$this->connectDb();
//选择数据库
$this->selectDb();
}
//私有的克隆方法,防止用户克隆对象
private function __clone()
{
}
//公共的静态方法
public static function getDbInstance(array $config)
{
if (!self::$db instanceof self) {
self::$db = new self($config);
}
return self::$db;
}
//私有的连接mysql服务器方法
private function connectDb()
{
if(!@self::$mysql = mysqli_connect($this->db_host,$this->db_user,$this->db_pass))
die('PHP连接MySQL服务器失败');
}
private function selectDb()
{
if(!mysqli_select_db(self::$mysql,$this->db_name))
die("选择数据库{$this->db_name}失败");
}
public function exec($sql)
{
$sql = strtolower($sql);
if(substr($sql,0,6) == 'select');
die('该方法不能执行SELECT语句');
//布尔值
return mysqli_query(self::$mysql,$sql);
}
public function query($sql)
{
$sql = strtolower($sql);
if(substr($sql,0,6) !='select')
die('该方法只能用select语句');
//返回结果集
return mysqli_query(self::$mysql,$sql);
}
}
$config = [
'db_host' => '127.0.0.1',
'db_name' => 'liran',
'db_user' => 'root',
'db_pass' => 'root',
'charset' => 'utf8',
];
//可以打印看下是不是一个对象
$db1 = Db::getDbInstance($config);
$db2 = Db::getDbInstance($config);
echo "<pre>";
var_dump($db1===$db2);