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