PHP Object Assignment vs Cloning

前端 未结 7 1267
后悔当初
后悔当初 2020-11-29 05:34

I know this is covered in the php docs but I got confused with this issue .

From the php docs :

$instance = new SimpleClass();
$assigned   =  $ins         


        
7条回答
  •  星月不相逢
    2020-11-29 06:04

    The difference between

     $assigned = $instance 
    

    and

     $assigned = clone $instance
    

    is that in first case you assign a reference of already existing object and in second one you create a new object and assign it to the variable.

    Moreover, when you use clone keyword you can use magic method __clone() which gives you better control on object cloning. From php manual:

    Once the cloning is complete, if a __clone() method is defined, then the newly created object's __clone() method will be called, to allow any necessary properties that need to be changed.

    From manual:

    A PHP reference is an alias, which allows two different variables to write to the same value. As of PHP 5, an object variable doesn't contain the object itself as value anymore. It only contains an object identifier which allows object accessors to find the actual object. When an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.

    Let me give you a live example

    $dateA = new \Datetime('2017-04-04');
    
    $dateB = $dateA; // $dateB references exactly the same object as $dateA
    
    $dateB->modify('+1 day');
    
    var_dump($dateA->format('Y-m-d')); //string(10) "2017-04-05" 
    var_dump($dateB->format('Y-m-d')); //string(10) "2017-04-05"
    
    
    // $dateA is still modified by the code above so it has 2017-04-05
    $dateC = clone $dateA; // we clone $dateA so it's a new object
    
    $dateC->modify('+1 day');
    
    var_dump($dateA->format('Y-m-d')); // string(10) "2017-04-05" 
    var_dump($dateC->format('Y-m-d')); // string(10) "2017-04-06"
    

    // side note for datetime I recommend using DatetimeImmutable instead of Datetime

    EDIT: internal types

    // create 2 integer variables $a and $b
    
    $a = 1;
    $b = 1;
    
    // create a new $c variable and assign the *value* of $a to that variable
    $c = $a;
    
    // create a new $d variable and assign a reference to $b variable
    $d = &$b;
    
    // increment $b, $c and $d variables
    $b++; 
    $c++;
    $d++;
    
    echo $a; // 1
    echo $b; // 3
    echo $c; // 2
    echo $d; // 3
    

    because $d references $b when we increment its value it'll also change the value of $b.

    The difference between internal objects like strings, int, float etc. is that they are passed by value and objects are passed by default via reference

    Notice: You cannot use clone with internal objects.

提交回复
热议问题