Validate PHP array and object passing by reference
  
  
  
  Aug 25, 2020
  
  
PHP
What you did
Copying an array containing objects with foreach can be an unexpected bug. (there were) Sample code verifies what happens when you copy an array, a two-dimensional array, an object, or an object containing an object, and how it works as expected.
#Environment
- PHP7.4
Implementation
array
Since the array is passed by value, if you assign it to another variable, rewriting the value of another variable does not affect the original variable.
$test = ['a'=>1,'b'=>2];
$test2 = $test;
$test2['a'] = 3;
var_dump($test);
exit;
/*
array (size=2)
  'a' => int 1 ← unchanged
  'b' => int 2
*/
Two-dimensional array
Same as a normal array.
$test = ['a'=>['c'=>1],'b'=>['d'=>2]];
$test2 = $test;
$test2['a']['c'] = 3;
var_dump($test);
exit;
/*
array (size=2)
  'a' =>
    array (size=1)
      'c' => int 1 ← unchanged
  'b' =>
    array (size=1)
      'd' => int 2
*/
Object (simply assigned) ← Addictive point 1
Since the object is passed by reference (exactly the object ID? Manual), the value of another variable Any changes will also affect the original variables.
$test = (object)['a'=>1,'b'=>2];
$test2 = $test;
$test2->a = 3;
var_dump($test);
exit;
/*
object(stdClass)[161]
  public'a' => int 3 ← changed
  public'b' => int 2
*/
object (clone and assign)
If you want to handle it as another object, use clone.
$test = (object)['a'=>1,'b'=>2];
$test2 = clone $test;
$test2->a = 3;
var_dump($test);
exit;
/*
object(stdClass)[161]
  public'a' => int 1 ← unchanged
  public'b' => int 2
*/
Object containing object (clone and assign) ← Addictive point 2
Even if cloned, the objects in the object will be passed by reference and retain the same reference (reference). (← see comment)
This is because PHP clone is a shallow copy. (Manuals)
$test = (object)['a'=>(object)['c'=>1],'b'=>(object)['d'=>2]];
$test2 = clone $test;
$test2->a->c = 3;
var_dump($test);
exit;
/*
object(stdClass)[210]
  public'a' =>
    object(stdClass)[161]
      public'c' => int 3 ← changed
  public'b' =>
    object(stdClass)[171]
      public'd' => int 2
*/
Object containing object (serialized & deserialized and assigned)
Manual describes to implement __clone, but this is not always possible.
The easiest way is to serialize and then deserialize.
$test = (object)['a'=>(object)['c'=>1],'b'=>(object)['d'=>2]];
$test2 = unserialize(serialize($test));
$test2->a->c = 3;
var_dump($test);
exit;
/*
object(stdClass)[211]
  public'a' =>
    object(stdClass)[161]
      public'c' => int 1 ← unchanged
  public'b' =>
    object(stdClass)[175]
      public'd' => int 2
*/
#Reference Thank you very much. https://qiita.com/A-Kira/items/749de2c83dfd07feb3b3 https://qiita.com/horikeso/items/29c8d412e57f2097855b