单例模式又称为职责模式,它用来在程序中创建一个单一功能的访问点,通俗地说就是实例化出来的对象是唯一的。
所有的单例模式至少拥有以下三种公共元素:
a, 它们必须拥有一个构造函数,并且必须被标记为private
b, 它们拥有一个保存类的实例的静态成员变量
c, 它们拥有一个访问这个实例的公共的静态方法
单例类不能再其它类中直接实例化,只能被其自身实例化。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。
单例模式 - 数据库单例实现
<?php
class db {
protected $conn;
protected $sql;
protected static $instance;
protected $db_config = [
'host' => 'localhost',
'user' => 'root',
'password' => '123456',
'database' => 'test_db',
];
private function __construct()
{
$db = $this->db_config;
$this->conn = mysqli_connect($db['host'], $db['user'], $db['password'], $db['database']);
if(!$this->conn){
die('数据库连接失败!');
}
}
public static function getInstance()
{
if(!(self::$instance instanceof self)) {
self::$instance = new self();
}
return self::$instance;
}
public function select($table, $condition=[], $field=[], $group='', $order='', $sort='asc', $limit='')
{
$where = '';
if(!empty($condition)) {
foreach($condition as $key => $value) {
$where .= "{$key} = {$value} and";
}
$where = 'where '.rtrim($where, 'and');
}
$field_str = '';
if(!empty($field)) {
foreach($field as $value) {
$field_str .= "{$value},";
}
$field_str = rtrim($field_str, ',');
}else{
$field_str = '*';
}
if($group) {
$group = "group by {$group}";
}
if($order) {
$order = "order by {$order}";
if(!$sort || 'asc' != strtolower($sort)){
$sort = 'desc';
}
$order .= " {$sort}";
}
$this->sql = "select {$field_str} from {$table} {$where} {$group} {$order} {$limit}";
$result_row = [];
$result_row = $this->query($this->sql);
return $result_row;
}
public function query($sql='')
{
if(empty($sql)){
die('未定义查询sql');
}
$this->sql = $sql;
$result = mysqli_query($this->conn, $this->sql);
$result_row = [];
$i = 0;
while($result && $row = mysqli_fetch_assoc($result)) {
foreach($row as $key => $value) {
$result_row[$i][$key] = $value;
}
$i++;
}
return $result_row;
}
public function insert()
{
return;
}
public function update()
{
return;
}
public function delete()
{
return;
}
public function getLastSql()
{
return $this->sql;
}
public function __call($name, $arguments)
{
$methods = [];
$reflects = new reflectionclass(__CLASS__);
foreach($reflects->getmethods() as $methodobj){
$methods[$methodobj->name] = 1;
}
if(!isset($methods[$name])) {
die('方法未定义!');
}
return;
}
public function __clone()
{
die('禁止克隆实例!');
}
public function __destruct(){}
}
使用示例 db::getInstance()->getLastSql();