deep clone in php

پرسیده شده
فعالیت 883 روز پیش
دیده شده 582 بار
2

سلام ، این تاپیک را باز کردم که هم تجربه ی خودم رو از چیزی که توی مقالات درباره object cloning خوندم بگم و  هم دوستان نظراتشون و تجربیاتشون رو بگن.

 

همون طور که استاد گفتن ، زمانی که ما از clone keyword استفاده میکنیم ، اون object مورد نظرمون copy by value میشه و copy by reference نمیشه ، حالا اگر داخل property هایی این Object دوباره object وجود داشته باشد ، دیگر فقط با استفاده از clone keyword نمیشه اون هارو کپی کرد ، و باید از روش deep clone استفاده کنیم.

 

نکته : در این مثالی که قراره بزنم ، فقط هدف اینه که بتونم به نحو احسنت این موضوع رو توضیح بدم برای همین ممکنه ، اصوله شی گرایی (encapsulation , inheritance , . . .) رو خیلی خوب رعایب نکنم.

 

اول از همه clone magic method رو توضیح میدم (متد جادویی clone) :

این متد مثل همون متد های جادویی construct و destruct هستش ، تفاوتی که داره اینه که زمانی که ما یک آبجکت رو clone میکنیم این متد جادوی call میشه و میتونیم یک سری کار ها باهاش انجام بدیم.

 

<?php
class SubObject
{
    static $instances = 0;
    public $instance;

    public function __construct() {
        $this->instance = ++self::$instances;
    }

    public function __clone() {
        $this->instance = ++self::$instances;
    }
}

class MyCloneable
{
    public $object1;
    public $object2;

    function __clone()
    {
        // Force a copy of this->object, otherwise
        // it will point to same object.
        $this->object1 = clone $this->object1;
    }
}

$obj = new MyCloneable();

$obj->object1 = new SubObject();
$obj->object2 = new SubObject();

$obj2 = clone $obj;


print("Original Object:\n");
print_r($obj);

print("Cloned Object:\n");
print_r($obj2);

?>

توضیحات درباره ی کد بالا

 

توی کلاس subObject ما دوتا پراپرتی داریم که یکی static هست و برای کلاس هستش یعنی وابسته به آبجکت نیست ، و دیگری هم که یک پراپرتی پابلیک معمولی هستش.

توی متد کانستراکتور ، اون پراپرتی ای که static هست و برابر با صفر هست رو پلاس پلاس کرده  و برابر با پراپرتی معمولی خودمون قرار داده ، که اینجا یعنی هم پراپرتی استاتیک یکی افزایش یافته و هم پراپرتی دیگر.

توی متد جادویی clone هم دقیقا همون کاری انجام میشه که زمانی که یک ابجکت میسازیم انجام میشه ، یعنی clone کردن یک آبجکت مثل این میمونه که یک آبجکت جدید ساخته باشیم ، یکم بریم جلو تر متوجه میشید دقیقا . . . 

توی کلاس myCloneable دوتا پراپرتی داریم ، object1 , object2 که همانطور که از اسمشون مشخصه قراره یک آبجکت بهشون assign بشه

توی متد جادویی clone این کلاس نوشته شده که زمانی که آبجکتی از این کلاس clone شد اون آبجکت شماره ی یک رو دوباره با خودش کلون کن . .  .


 

بعد از اینکه کلس هامون رو پیاده سازی کردیم ، یک آبجکت از کلاس myCloneable ساختیم و پراپرتی های آنرا به ترتیب assign کردیم با آبجکتی از کلاس subClass

 

الان در این لحظه متد سازنده ی کلاس subClass کال میشه و هردو پراپرتی برابر با مقدار یک میشن ، ولی ما فقط با پراپرتی معلمولی کار داریم و با پراپرتی استاتیک کاری نداریم چون متعلق به کلاس هستش.

 

برای پراپرتی object2 هم همین اتفاق میوفته و برابر با مقدار دو میشوند

 

 

بعد از اون اومده از آبجکت $obj کلون کرده و ریخته توی آبجکت $obj2 

 

 الان ، تابع جادووی کلون که برای کلاس myCloneable هست صدا زده میشه 

 

توی این متد گفته شده زمانی که کال شد پراپرتی object1 رو با خودش کلون کنه ، این پراپرتی یک آبجکت از کلاس subclass هستش و الان باید بریم متد جادویی کلون کلاس ساب کلس رو برسی کنیم.

که درونش همون اتفاقی میوفته که زمانی که یک ابجکت میسازیم رخ میدهد. پس یعنی مقدار پراپرتی افزایش میابد

 

تحلیل خروجی کد :(

 

Original Object:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 1
        )

    [object2] => SubObject Object
        (
            [instance] => 2
        )

)
Cloned Object:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 3
        )

    [object2] => SubObject Object
        (
            [instance] => 2
        )

)

الان اگر دقت کنید ، خروجی cloned object1 برابر با 3 است چون ما توی متد جادوییش فقط گفته بودیم object1 رو با خودش کلون کن و object2 رو که نگفته بودیم برابر با همون مقدری هست که در original object وجود داره

امیدوارم براتون مفید بوده باشه

برای اطلاعات بیشتر این بخش را بخوانید.

فایل پیوست

مسعود هارونی
مسعود هارونی

5 آبان 00