PHP中的淺拷貝和深拷貝

來源:互聯網
上載者:User

深拷貝和淺拷貝的概念,一般程式員都很熟悉,網上的概念解析也很多。可以查看http://cnn237111.blog.51cto.com/2359144/589507。

PHP中提供了一直對象複製的操作,clone。文法頗為簡單:

$a = clone $b;
這時候就得到a對象就複製了b對象。如果b對象中的成員都是實值型別,那也就沒什麼關係,a對象中的成員和b變數中的成員都是各自佔用獨立的記憶體空間。但是由於這個複製操作是淺拷貝,所以如果b的成員中有參考型別的資料,那麼a對象的成員並未真正複製該成員,而是和b對象的成員共用了這一個對象。看下面的樣本。

<?phpclass A{    public $info="this is a";}class B{    public $a;    function __construct()    {        $this->a=new A;    }    public $info="this is b";}$b1=new B();echo "clone操作<br>";$b2=clone $b1;echo"b1的值<br>";echo "b1的info:{$b1->info}<br>";echo "b1的a的info:{$b1->a->info}<br><br>";echo"b2的值<br>";echo "b2的info:{$b2->info}<br>";echo "b2的a的info:{$b2->a->info}<br><br>";$b1->info="this value is updated(this is b)";$b1->a->info="this value is updated(this is a)";echo"修改b1後,b1的值<br>";echo "b1的info:{$b1->info}<br>";echo "b1的a的info:{$b1->a->info}<br><br>";echo"修改b1後,b2的值<br>";echo "b2的info:{$b2->info}<br>";echo "b2的a的info:{$b2->a->info}<br><br>";echo"判斷b1的a和b2的a是否為同一對象:" ,$b1->a===$b2->a;?>
運行結果如下:

clone操作

b1的值

b1的info:this is b

b1的a的info:this is a


b2的值
b2的info:this is b
b2的a的info:this is a

修改b1後,b1的值
b1的info:this value is updated(this is b)
b1的a的info:this value is updated(this is a)

修改b1後,b2的值
b2的info:this is b
b2的a的info:this value is updated(this is a)

判斷b1的a和b2的a是否為同一對象:1

可以看到,修改b1中參考型別a的值後,b2中的a的值也跟著變了。進一步,可以判斷出b1的a和b2的a是同一個對象。

和C++一樣,php也提供了拷貝建構函式,以此可以自訂複製行為,實現深拷貝。PHP通過在對象的定義中實現__clone()方法來完成拷貝建構函式。這個函數在對象被複製的時候調用。還是之前的代碼,修改一下。

<?phpclass A{    public $info="this is a";}class B{    public $a;    function __construct()    {        $this->a=new A;    }    public $info="this is b";                                 public function __clone()    {        echo "拷貝建構函式開始調用<br>";        $new_object=new A;        $new_object->info=$this->a->info;        $this->a=$new_object;    }}$b1=new B();echo "clone操作<br>";$b2=clone $b1;echo "b1的值<br>";echo "b1的info:{$b1->info}<br>";echo "b1的a的info:{$b1->a->info}<br><br>";echo"b2的值<br>";echo "b2的info:{$b2->info}<br>";echo "b2的a的info:{$b2->a->info}<br><br>";$b1->info="this value is updated(this is b)";$b1->a->info="this value is updated(this is a)";echo"修改b1後,b1的值<br>";echo "b1的info:{$b1->info}<br>";echo "b1的a的info:{$b1->a->info}<br><br>";echo"修改b1後,b2的值<br>";echo "b2的info:{$b2->info}<br>";echo "b2的a的info:{$b2->a->info}<br><br>";echo"判斷b1的a和b2的a是否為同一對象:" ,$b1->a===$b2->a;?>
運行完畢後,
clone操作
拷貝建構函式開始調用
b1的值
b1的info:this is b
b1的a的info:this is a

b2的值
b2的info:this is b
b2的a的info:this is a

修改b1後,b1的值
b1的info:this value is updated(this is b)
b1的a的info:this value is updated(this is a)

修改b1後,b2的值
b2的info:this is b
b2的a的info:this is a

判斷b1的a和b2的a是否為同一對象:

最後可以看到,b1的a和b2的a同一個對象是false,所以列印了一個Null 字元串。

————————————————————————

上面的方法實現了魔法方法__clone,在這個方法中定義自己的深拷貝方式,這種寫法比較麻煩,如果對象修改了,這個方法也得修改。事實上對成員進行深拷貝,可以採用將對象序列化後再還原的方式。這種寫法可能效能上有所損失,但是確實最便捷的。PHP中,使用如下語句實現深拷貝:

$b2 = unserialize(serialize($b1));//序列化然後還原序列化

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.