将Looped DateTime值拉到数组
I have the following code whereby $Clinics is a multidimensional object array in the following format:
Array
(
[0] => Clinics Object
(
[PlanID] => 1
[id] => 1
[ClinicCode] => X123ABCD1
[ClinicDesc] => Test Description
[SchDay] => Monday
[SchWeek] =>
[SchWeekBetween] => 1
)
[158] => Clinics Object
(
[PlanID] => 1
[id] => 159
[ClinicCode] => Y234BCDE2
[ClinicDesc] => Test Description
[SchDay] => Monday
[SchWeek] =>
[SchWeekBetween] => 1
)
)
I'm using the below code to loop through each object, starting on the Scheduled Day (SchDay) one a week, and daily if SchDay is daily.
$StartDate = new DateTimeImmutable("2018-04-01");
$EndDate = new DateTimeImmutable("2019-03-31");
$Output = array();
foreach ($Clinics as $Clinic) {
// Set First Date of loop period
if ($Clinic->SchDay == "Daily") {
$ClinicStartDate = $StartDate->format("d-m-Y");
$SchCount = "+1 day";
} else {
$ClinicStartDate = "First ".$Clinic->SchDay." of ".$StartDate->format("F Y");
$SchCount = "+7 days";
}
// Loop through Dates and add to array
for($i = new DateTime($ClinicStartDate); $i <= $EndDate; $i->modify($SchCount)){
$Clinic->Date = $i;
$Output[] = $Clinic;
}
};
print_r($Output);
The issue I have is that when I print the array, the Date value is the same for each clinic iteration - the last date of the loop, and the array isn't capturing each DateTime as per the for loop. I think I understand why it is doing this but I can't figure out how to get around it.
The loop instantiates the object only once. Then you are modifying the object with each iteration and then assigning it's reference to the array. All the assignments reference the same object.
It's easy to get around this but you'll have to instantiate a new datetime for each assignment:
for ($i = new DateTime("2018-05-01"); $i <= $EndDate; $i->modify('+7 days')) {
$Clinic->Date = new DateTime($i->format("Y-m-d"));
$Output[] = $Clinic;
}
http://php.net/manual/en/language.oop5.references.php
EDIT: Here is a working example. All you have to do is copy paste to see it in action.
<?php
$StartDate = new DateTimeImmutable("2018-04-01");
$EndDate = new DateTimeImmutable("2019-03-31");
$Output = array();
for ($i = new DateTime("2018-05-01"); $i <= $EndDate; $i->modify('+7 days')) {
$Output[] = new DateTime($i->format("Y-m-d"));
}
var_dump($Output);
Managed to get the desired output with the following:
for($i = new DateTime($ClinicStartDate); $i <= $EndDate; $i->modify($SchCount)){
$Output[$ArrayCount]['PlanID'] = $Clinic->PlanID;
$Output[$ArrayCount]['id'] = $Clinic->id;
$Output[$ArrayCount]['ClinicCode'] = $Clinic->ClinicCode;
$Output[$ArrayCount]['SchDay'] = $Clinic->SchDay;
$Output[$ArrayCount]['SchWeek'] = $Clinic->SchWeek;
$Output[$ArrayCount]['SchWeekBetween'] = $Clinic->SchWeekBetween;
$Output[$ArrayCount]['Date'] = new DateTime($i->format("Y-m-d"));
$ArrayCount++;
}