Variable References and Changes

I’ve typically been a C# programmer, but I’m helping with a small project written in PHP. I’m having a bit of difficulty with what seems to be related to variable references, and then changing variable values in a loop.

I’m trying to create an array of “Day” objects to help the user create a plan on a timeline, and I want to maintain reference to the actual calendar dates as well as the plan values. So any given day may be the 100th day in the plan, but actually the 300th day in the current calendar year.

//I have this as the Day object constructor:

		function __construct($iday, $iweek, $imonth, $iyear, $idate) {           
				$this->PlanDay = $iday;
				$this->PlanWeek = $iweek;
				$this->PlanMonth = $imonth;
				$this->PlanYear = $iyear; 
		 
				$this->Date = $idate;
				$this->DateMonth = $this->Date->format('n');
				$this->DateDay = $this->Date->format('j');  
				$this->DateYear = $this->Date->format('Y');
		 
				$this->DayOfWeek = $this->Date->format('w') + 1;
				$this->DayOfYear = $this->Date->format('z') + 1;
		
				$this->WeekOfYear = $this->Date->format("W"); 
				$calcDate = new \DateTime($this->Date->format("Y-m-01")); //used to subtract all previous weeks to get the Week number of the month.
				$this->WeekOfMonth = $this->WeekOfYear - $calcDate->format("W") + 1;    
			}
 	//Then, I have this code that iterates through to create the array:

	$cal = array();
	
	$earliestDate = new DateTime('2014-01-01');
	$maxDate = new DateTime('2015-06-01');
	$previousDate = $compareDate = $earliestDate;
	
	$iday = $iweek = $imonth = $iyear = 1;

	while($compareDate <= $maxDate) {
		$thisDay = new obj\Day($iday, $iweek, $imonth, $iyear, $compareDate);
		array_push($cal, $thisDay);
		
		$iday++;
		if($compareDate->format("W") != $previousDate->format("W")){
			$iweek++;
		}
		if($compareDate->format('n') != $previousDate->format('n')){
			$imonth++;
		}
		if($compareDate->format('Y') != $previousDate->format('Y')){
			$iyear++;
		}
		$previousDate = $compareDate;
		$compareDate->modify('+1 day');
	} 

But what I’m seeing is that every single Day object ends up with the same $this->Date value (being the last one or equal to $maxDate), despite that the values for $this->DateYear, $this->DateMonth, and $this->DateDay are iterating.

Then the PlanYear ($iyear), PlanMonth ($imonth) and PlanDay ($iday) don’t seem to increment at all.

I’m guessing that I’m making a pretty obvious mistake that I’m not catching because I’m not as familiar with PHP as I’d like to be.

Any help is appreciated!

Thanks!

The problem is caused by the fact that PHP assigns/passes objects by reference. $previousDate and $compareDate are actually references to the same object, and likewise all your Day objects are also receiving a reference to the object.

The solution depends on which version of PHP that you’re using… for 5.5 and higher you could use the DateTimeImmutable class, which returns a new object when you modify the date instead of altering the existing one:

$earliestDate = new DateTimeImmutable('2014-01-01');

// In your while loop
$previousDate = $compareDate;
$compareDate  = $compareDate->modify('+1 day');

If you’re using an older version of PHP then you can clone the DateTime objects instead:

// e.g
$previousDate = clone $compareDate;

Great answer! Thank you!

I ended up using the clone method. Started working like a charm.

I figured it must have been variable as reference, but when I searched for that topic I only saw the syntax for forcing reference (using the & character)…but never saw how to use Immutable or Clone.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.