企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## **单例模式** >[info]目的:**`确保唯一性`**,保证一个类仅有一个实例,并提供一个访问它的全局访问点。例如同一时间只能允许一台设备登陆 应用场景:数据库连接、缓存操作、分布式存储 分布式下的单例模式 分布式可以说是当下很热门的概念,那么单例模式在分布式环境下是否依然实用呢?我以分布式Session举例吧,分布式Session常见的做法就是用一个全局缓存(如Redis)存储Session对象,多个Web应用共享这个Session对象,这个不就是活生生的单例吗?还有就是分布式ID某种意义上也可以说是单例模式,起码生成出来的分布式ID需要全局唯一。 特点: * 静态方法检测唯一性并实例化对象 * 私有的final构造函数 * 私有的克隆魔术方法确保不能被复制 * 私有的静态属性存放唯一的类对象 ``` class test { //保存类实例的私有静态成员变量 private static $_instance; //定义一个私有的构造函数,确保单例类不能通过new关键字实例化,只能被其自身实例化(一定还要加final否则可以继承重写构造函数) private final function __construct() { echo 'test __construct'; } //定义私有的__clone()方法,确保单例类不能被复制或克隆 private function __clone() {} public static function getInstance() { //检测类是否被实例化 if ( ! (self::$_instance instanceof self) ) { self::$_instance = new test(); } return self::$_instance; } } //调用单例类 test::getInstance(); ``` pdo单例 ``` <?php class Database { protected static $_instance = null; protected $dsn; public $dbh; /** * 构造 * * @return Database */ private final function __construct($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset) { try { $this->dsn = 'mysql:host='.$dbHost.';dbname='.$dbName; $this->dbh = new PDO($this->dsn, $dbUser, $dbPasswd); $this->dbh->exec('SET character_set_connection='.$dbCharset.', character_set_results='.$dbCharset.', character_set_client=binary'); } catch (PDOException $e) { throw new Exception($e->getMessage(), 1); } } /** * 防止克隆 * */ private function __clone() {} /** * 获取PDO的单例实例 * * @return Object */ public static function getInstance($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset="utf8") { if (self::$_instance === null) { self::$_instance = new self($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset); echo 1111; } return self::$_instance; } } $pdo=Database::getInstance("localhost","root","","test"); Database::getInstance("localhost","root","","test"); Database::getInstance("localhost","root","","test"); Database::getInstance("localhost","root","","test"); Database::getInstance("localhost","root","","test"); $res=$pdo->dbh->query("select * from o2o_user"); $result = $res->fetchAll(PDO::FETCH_BOTH); ```