PHP单例模式使用clone
我們來看下PHP單例模式是否能夠clone,先上一段代碼。
<?php class Singleton {private static $object;private $name;private function __construct(string $name) {$this->name= $name;}public static function getInstance(string $name) {if (self::$object == null) {$object = new Singleton($name);}return $object;} }這是一個(gè)單例模式的簡單實(shí)現(xiàn),構(gòu)造函數(shù)是private訪問修飾符,所以不能直接調(diào)用,例如這樣new一個(gè)會(huì)報(bào)錯(cuò):
$c = new Singleton("c");加上如上代碼執(zhí)行會(huì)報(bào)錯(cuò),
~/Develop/PHP/test php singleton.php PHP Fatal error: Uncaught Error: Call to private Singleton::__construct() from invalid context in /Users/mark/Develop/PHP/test/singleton.php:23 Stack trace: #0 {main} thrown in /Users/mark/Develop/PHP/test/singleton.php on line 23
我們通過提供getInstance()靜態(tài)方法來實(shí)現(xiàn)實(shí)例化,并保證實(shí)例只有一個(gè)。如果我們?cè)偌由蟘lone會(huì)怎么樣呢,繼續(xù)看代碼:
$c = new Singleton("c"); $a = Singleton::getInstance("a"); $b = clone $a;var_dump($a); var_dump($b);代碼執(zhí)行的結(jié)果是這樣的,
object(Singleton)#1 (1) {["name":"Singleton":private]=>string(1) "a" } object(Singleton)#2 (1) {["name":"Singleton":private]=>string(1) "a" }對(duì)象就是對(duì)象,模式只是人為的控制,看下官方對(duì)對(duì)象復(fù)制的描述
對(duì)象復(fù)制可以通過 clone 關(guān)鍵字來完成(如果可能,這將調(diào)用對(duì)象的 __clone() 方法)。對(duì)象中的 __clone() 方法不能被直接調(diào)用。
$copy_of_object = clone $object; 當(dāng)對(duì)象被復(fù)制后,PHP 5
會(huì)對(duì)對(duì)象的所有屬性執(zhí)行一個(gè)淺復(fù)制(shallow copy)。所有的引用屬性 仍然會(huì)是一個(gè)指向原來的變量的引用。
__clone(): void 當(dāng)復(fù)制完成時(shí),如果定義了 __clone() 方法,則新創(chuàng)建的對(duì)象(復(fù)制生成的對(duì)象)中的 __clone() 方法會(huì)被調(diào)用,可用于修改屬性的值(如果有必要的話)。
然后我們?cè)僭黾觃_clone方法做下實(shí)驗(yàn),
public function __clone() {$this->name = "clone";}再次執(zhí)行代碼,
object(Singleton)#1 (1) {["name":"Singleton":private]=>string(1) "a" } object(Singleton)#2 (1) {["name":"Singleton":private]=>string(5) "clone" }返回的結(jié)果證明對(duì)象clone是成功的,但是這樣不符合單例模式的要求,那么如何禁止單例模式下的clone呢,根據(jù)php官方的文檔,我們知道__clone會(huì)在克隆操作完成后被調(diào)用,要能夠被調(diào)用就必須是public訪問修飾符,如果改為private,這個(gè)方法就不能被調(diào)用了,示例如下:
private function __clone() {$this->name = "clone";}再次執(zhí)行代碼,得到以下報(bào)錯(cuò):
PHP Fatal error: Uncaught Error: Call to private Singleton::__clone() from context '' in /Users/mark/Develop/PHP/test/singleton.php:24 Stack trace: #0 {main}thrown in /Users/mark/Develop/PHP/test/singleton.php on line 24證明在調(diào)用__clone方法時(shí)出錯(cuò)了,這樣可以來禁止單例的clone
參考:
https://www.php.net/manual/zh/language.oop5.cloning.php
總結(jié)
以上是生活随笔為你收集整理的PHP单例模式使用clone的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蒙特卡罗方法(Monte Carlo m
- 下一篇: php apk包信息,php提取apk包