溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

PHP對象復(fù)制舉例分析

發(fā)布時(shí)間:2021-11-25 16:42:11 來源:億速云 閱讀:133 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容主要講解“PHP對象復(fù)制舉例分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“PHP對象復(fù)制舉例分析”吧!

原型模式可以看作是對象復(fù)制中的一個(gè)重要內(nèi)容。在學(xué)習(xí)原型模式時(shí),我們了解到對象中的引用變量,也就是變量也是一個(gè)對象時(shí),直接復(fù)制這個(gè)對象會導(dǎo)致其中的引用變量還是指向同一個(gè)對象。是不是有點(diǎn)繞,我們還是用例子來說明:

// clone方法
class testA{
   public $testValue;
}
class A
{
   public static $reference = 0;
   public $instanceReference = 0;
   public $t;

   public function __construct()
   {
       $this->instanceReference = ++self::$reference;
       $this->t = new testA();

   }

   public function __clone()
   {
       $this->instanceReference = ++self::$reference;
       $this->t = new testA();
   }
}

$a1 = new A();
$a2 = new A();
$a11 = clone $a1;
$a22 = $a2;

var_dump($a11); // $instanceReference, 3
var_dump($a22); // $instanceReference, 2

$a1->t->testValue = '現(xiàn)在是a1';
echo $a11->t->testValue, PHP_EOL; // ''


$a2->t->testValue = '現(xiàn)在是a2';
echo $a22->t->testValue, PHP_EOL; // 現(xiàn)在是a2
$a22->t->testValue = '現(xiàn)在是a22';
echo $a2->t->testValue, PHP_EOL; // 現(xiàn)在是a22

// 使用clone后
$a22 = clone $a2;
var_dump($a22); // $instanceReference, 4

$a2->t->testValue = '現(xiàn)在是a2';
echo $a22->t->testValue, PHP_EOL; // NULL
$a22->t->testValue = '現(xiàn)在是a22';
echo $a2->t->testValue, PHP_EOL; // 現(xiàn)在是a2
 

首先,通過變量的變化,我們可以看出使用clone關(guān)鍵字的對象復(fù)制會調(diào)用__clone()方法。這個(gè)魔術(shù)方法正在原型模式的核心所在。在這個(gè)方法中,我們可以重新實(shí)例化或者定義對象中的引用成員。通過clone,我們讓t成為了新的對象,從而避免引用帶來的問題。

在對象的復(fù)制中,我們需要特別注意的遞歸引用的問題。也就是對象內(nèi)部引用了自身,將會導(dǎo)致來回的重復(fù)引用形成遞歸死循環(huán)。

// 循環(huán)引用問題
class B
{
   public $that;

   function __clone()
   {
       // Segmentation fault: 11
       $this->that = clone $this->that;
       // $this->that = unserialize(serialize($this->that));
       // object(B)#6 (1) {
       //     ["that"]=>
       //     object(B)#7 (1) {
       //       ["that"]=>
       //       object(B)#8 (1) {
       //         ["that"]=>
       //         *RECURSION*  無限遞歸
       //       }
       //     }
       //   }
   }
}

$b1 = new B();
$b2 = new B();
$b1->that = $b2;
$b2->that = $b1;

$b3 = clone $b1;

var_dump($b3);

B類中的that指向自身的實(shí)例,兩個(gè)對象相互指向后再進(jìn)行復(fù)制,就會出現(xiàn)這種死循環(huán)的情況。使用序列化和反序列化輸出后,我們會看到RECURSION的引用提示。這就是形成了遞歸的死循環(huán)。這種情況一定要極力避免。

上述例子中,我們使用了序列化和反序列化這一招來解決引用問題。對象復(fù)制的對象變量來說(對象變量里面還有更多層次的引用變量),這種方式能夠一次性地在最頂層的對象__clone()方法中解決引用問題。

到此,相信大家對“PHP對象復(fù)制舉例分析”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

php
AI