Nomikos Strigkos
Nomikos Strigkos

Reputation: 141

PHP Object : Both copy getting affected by change in one

I am writing here because I amt totally confused of what the equal operator means for objects in php. I run the example bellow...

  $currentDay = new DateTime();
  $dayBefore = new DateTime();

  $dayBefore = $currentDay;

  $dayBefore->modify('-1 day');
  $currentDay->modify('-1 month');
  $dayBefore->modify('-1 year');
  $currentDay->modify('-5 day');

  echo 'Current day : ';
  print_r($currentDay);
  echo '<br />';
  echo 'Day before : ';
  print_r($dayBefore);

and the result is

  <!-- Output -->
  Current day : DateTime Object ( [date] => 2017-01-15 10:54:13 [timezone_type] => 3 [timezone] => Europe/Paris ) 
  Day before : DateTime Object ( [date] => 2017-01-15 10:54:13 [timezone_type] => 3 [timezone] => Europe/Paris ) 

As you can see whatever operation is being applied to one of the dates, it is also being applied to the other one. So, are $dayBefore and $currentDay in some kind of synchronization? Or one of them is an alias of the other?

Upvotes: 0

Views: 950

Answers (4)

trincot
trincot

Reputation: 350117

Object variables are references: they reference a memory location where all the object properties are stored. When you assign one such variable to another, they will share the same reference. Whichever mutation you apply to one, will affect that memory location somewhere, and so that change is visible via either of the two variables, since they both refer to the same location.

After the first initialisation of your two variables, you have indeed created two separate object references:

enter image description here

However, once you copy one reference to the other, you effectively lose connection with one of those two objects -- it becomes unreachable, and will eventually be cleared from memory:

enter image description here

In this situation, when you apply a method such as ->modify() on any of the two variables, you will be affecting the single set of object properties referred to:

enter image description here

Upvotes: 4

Touheed Khan
Touheed Khan

Reputation: 2151

Using $dayBefore = $currentDay; will assign only object reference to another object.

By assigning an object instance to a new variable, as above, one creates only a new reference and the object’s state information is shared by both reference variables.

You are copying one object to other, so any change will reflect on both object.

Use clone to make copy of object rather than reference :

$dayBefore = clone $currentDay;

Refer this documentation for detail.

Object Cloning in PHP

Upvotes: 3

Tschallacka
Tschallacka

Reputation: 28722

The problem lies in this:

$currentDay = new DateTime();
$dayBefore = new DateTime();

$dayBefore = $currentDay; 

At the last line above, you're throwing away the datetime object you defined on the second line and replacing it with the datetime object you defined on the first line.

So all state changes you perform(addyear etc) will be done on the datetime object defined on the first line.

$currentDay and $dayBefore point to the same object

          DATETIME OBJECT
         /               \
        /                 \
       /                   \
    $currentDay          $dayBefore

Please read more on https://secure.php.net/manual/en/language.oop5.references.php

Upvotes: 1

Jon
Jon

Reputation: 431

In the line $dayBefore = $currentDay; you are assigning $dayBefore as a link to $currentDay. Therefore any change to $currentDay also affects $dayBefore.

If you don't want this behaviour you need to clone the object with

$dayBefore = clone $currentDay;

Upvotes: 2

Related Questions