2017-10-21 26 views
0

我知道標題看起來很奇怪,但這正是我遇到的情況。
我創建了一個funtion這需要DateTimeinteger和返回日期的array,這是我的代碼:
PHP:循環後數組的值發生了變化

public static function generateAfterDate(\DateTime $from, $number){ 
     $days = array(); 
     array_push($days, $from); 
     for($i = 1; $i <= $number; $i++){ 
      $from = $from->modify('+1 day'); 
      $days[] = $from; 
      var_dump($days[$i]->format('d/m/Y'));//---The first var_dump 
     } 
     foreach ($days as $day){ 
      var_dump($day->format('d/m/Y'));//--The second var_dump 
     } 
     die; 
     return $days; 
    } 

generateAfterDate(new \DateTime(), 7); 

正如你可以看到我使用的是相同的陣列var_dump數據,我得到兩個不同的結果:
第一個給了我這個

string(10) "22/10/2017" string(10) "23/10/2017" string(10) "24/10/2017" string(10) "25/10/2017" string(10) "26/10/2017" string(10) "27/10/2017" string(10) "28/10/2017" 

,第二個給了我這個結果

string(10) "28/10/2017" string(10) "28/10/2017" string(10) "28/10/2017" string(10) "28/10/2017" string(10) "28/10/2017" string(10) "28/10/2017" string(10) "28/10/2017" string(10) "28/10/2017" 

可有人請解釋一下嗎?

回答

2

發生這種情況是因爲包含對象的變量(如DateTime對象)實際上不包含該對象,而是包含對象的內存地址的引用

所以通過將$from變量到您$days數組,你是不是把你的DateTime對象的副本,其當前狀態到數組,但你把存儲器地址引用的拷貝到數組。因此,修改$from引用指向的日期時間也將修改您的$days數組中每個條目引用的相同日期時間。

您需要做的是將DateTime對象及其狀態複製到新的DateTime實例中,並將其添加到數組中。幸運的是,PHP有一個簡單的方法來做到這一點:clone

array_push($days, clone $from); 
for($i = 1; $i <= $number; $i++){ 
    $from = $from->modify('+1 day'); 
    $days[] = clone $from; 
    var_dump($days[$i]->format('d/m/Y'));//---The first var_dump 
} 

現在你$days陣列仍將包含內存地址的引用,但它會包含一個DateTime物件的唯一實例不同的內存地址每個條目。

+0

哦我現在看到了,謝謝你的解釋。 – SlimenTN

1

因爲我認爲你的第一個var_dump與你的預期結果是正確的,所以第二個只返回最後一個值,因爲foreach循環在你使用變量$ day時創建一個數組副本,所以它總是會引用最後一個正確的代碼是

foreach ($days as $key=>$day){ 
     var_dump($days[$key]->format('d/m/Y'));//--The second var_dump 
    } 
相關問題