一、什么是单例模式?
单例即一个类是能有一个实例,并提供一个当前类的全局唯一访问入口(getInstance)。防止类被多次实例化和clone。
二、单例模式
代码如下(示例):
<?php class Singleton { private static $instance = null; // 禁止被实例化 private function __construct() { } // 禁止clone private function __clone() { } // 实例化自己并保存到$instance中,已实例化则直接调用 public static function getInstance(): object { if (empty(self::$instance)) { self::$instance = new self(); } return self::$instance; } public function test(): string { return '这是一个单例模式'; } } // 两次调用返回同一个实例 $single1 = Singleton::getInstance(); $single2 = Singleton::getInstance(); var_dump($single1, $single2); echo $single1->test(); // new Singleton(); // Fatal error: Uncaught Error: Call to private Singleton::__construct() from invalid context // clone $single1; // Fatal error: Uncaught Error: Call to private Singleton::__construct() from invalid context
输出:
object(Singleton)#1 (0) { } object(Singleton)#1 (0) { } 这是一个单例模式
2.单例模式的应用
tp6框架容器中单例模式:(示例):
/** * 容器管理类 支持PSR-11 */ class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, Countable { /** * 容器对象实例 * @var Container|Closure */ protected static $instance; /** * 容器中的对象实例 * @var array */ protected $instances = []; /** * 容器绑定标识 * @var array */ protected $bind = []; /** * 容器回调 * @var array */ protected $invokeCallback = []; /** * 获取当前容器的实例(单例) * @access public * @return static */ public static function getInstance() { if (is_null(static::$instance)) { static::$instance = new static; } if (static::$instance instanceof Closure) { return (static::$instance)(); } return static::$instance; } // ... }
数据库连接:
<?php class SingletonMysql { private static $instance = null; private static $db = null; const DB_TYPE = 'mysql'; const DB_HOST = '127.0.0.1'; const DB_NAME = 'mysql'; const DB_USER = 'root'; const DB_PASS = '123456'; const DB_MS = self::DB_TYPE . ':host=' . self::DB_HOST . ';' . 'dbname=' . self::DB_NAME; // 数据库连接 private function __construct() { try { self::$db = new PDO(self::DB_MS, self::DB_USER, self::DB_PASS); self::$db->query('set names utf8mb4'); self::$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { die('error:' . $e->getMessage()); } } // 禁止clone private function __clone() { } public static function getInstance(): object { if (empty(self::$instance)) { self::$instance = new self(); } return self::$instance; } public function query(string $sql = ''): array { return self::$db->query($sql)->fetch(); } } $mysql = SingletonMysql::getInstance(); var_dump($mysql->query('SELECT VERSION();'));
输出:
array(2) { ["VERSION()"]=> string(6) "5.7.26" [0]=> string(6) "5.7.26" }