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;} }這是一個單例模式的簡單實現(xiàn),構(gòu)造函數(shù)是private訪問修飾符,所以不能直接調(diào)用,例如這樣new一個會報錯:
$c = new Singleton("c");加上如上代碼執(zhí)行會報錯,
~/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)方法來實現(xiàn)實例化,并保證實例只有一個。如果我們再加上clone會怎么樣呢,繼續(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" }對象就是對象,模式只是人為的控制,看下官方對對象復(fù)制的描述
對象復(fù)制可以通過 clone 關(guān)鍵字來完成(如果可能,這將調(diào)用對象的 __clone() 方法)。對象中的 __clone() 方法不能被直接調(diào)用。
$copy_of_object = clone $object; 當對象被復(fù)制后,PHP 5
會對對象的所有屬性執(zhí)行一個淺復(fù)制(shallow copy)。所有的引用屬性 仍然會是一個指向原來的變量的引用。
__clone(): void 當復(fù)制完成時,如果定義了 __clone() 方法,則新創(chuàng)建的對象(復(fù)制生成的對象)中的 __clone() 方法會被調(diào)用,可用于修改屬性的值(如果有必要的話)。
然后我們再增加__clone方法做下實驗,
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é)果證明對象clone是成功的,但是這樣不符合單例模式的要求,那么如何禁止單例模式下的clone呢,根據(jù)php官方的文檔,我們知道__clone會在克隆操作完成后被調(diào)用,要能夠被調(diào)用就必須是public訪問修飾符,如果改為private,這個方法就不能被調(diào)用了,示例如下:
private function __clone() {$this->name = "clone";}再次執(zhí)行代碼,得到以下報錯:
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方法時出錯了,這樣可以來禁止單例的clone
參考:
https://www.php.net/manual/zh/language.oop5.cloning.php
總結(jié)
以上是生活随笔為你收集整理的PHP单例模式使用clone的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蒙特卡罗方法(Monte Carlo m
- 下一篇: 使用 BigDecimal 进行浮点数运