PHP Массив ассоциативных массивов перезаписывается каждый цикл

Я пытаюсь создать массив периодов (с началом и концом каждого) в цикле, но каждый раз, когда я использую add() для временных переменных, все значения внутри окончательного массива перезаписываются во временную переменную. ценить.

Мой код:

$newPeriods = []; //final array

$firstPeriod = array(
    "start"=>new DateTime("2022/10/05 16:30:00"), 
    "end"=>new DateTime("2022/10/05 16:45:00")
);

for ($i = 0; $i < 3; $i++) {
    //if not first repetition
    if (isset($newPeriod)) {
        $newPeriod["start"] = end($newPeriods)["start"];
        $newPeriod["end"] = end($newPeriods)["end"];

        //I figured out that the array $newPeriods gets rewriten in the next two lines
        $newPeriod["start"]->add(new DateInterval('P1W'));
        $newPeriod["end"]->add(new DateInterval('P1W'));
    }
    //first repetition
    else {
        $newPeriod['start'] = $firstPeriod["start"];
        $newPeriod['end'] = $firstPeriod["end"];
    }

    var_dump($newPeriod); //this prints what I expect to find in $newPeriods

    array_push($newPeriods, $newPeriod);
}

var_dump($newPeriods);//all elements are like the last $newPeriod

Обобщенный вывод из var_dump($newPeriod) (как и ожидалось) (значения являются объектами DATETIME)

array(2) {
  ["start"]=>"2022-10-05 23:55:00.000000"
  ["end"]=>"2022-10-06 00:15:00.000000"
}
array(2) {
  ["start"]=>"2022-10-12 23:55:00.000000"
  ["end"]=>"2022-10-13 00:15:00.000000"
}
array(2) {
  ["start"]=>"2022-10-19 23:55:00.000000"
  ["end"]=>"2022-10-20 00:15:00.000000"
}

Обобщенный вывод из var_dump($newPeriods) (не так, как ожидалось, поскольку все значения повторяются):

array(3) {
  [0]=>
  array(2) {
    ["start"]=>"2022-10-19 23:55:00.000000"
    ["end"]=>"2022-10-20 00:15:00.000000"
  }
  [1]=>
  array(2) {
    ["start"]=>"2022-10-19 23:55:00.000000"
    ["end"]=>"2022-10-20 00:15:00.000000"
  }
  [2]=>
  array(2) {
    ["start"]=>"2022-10-19 23:55:00.000000"
    ["end"]=>"2022-10-20 00:15:00.000000"
  }
}

Вот как это работает, и вы приказали PHP сделать это таким образом. Обратите внимание, что DateTime не является неизменным, если вам нужен неизменяемый вариант, используйте DateTimeImmutable, так как он даст вам новый объект, когда вы добавите к нему точку. в противном случае новый элемент относится к одному и тому же (модифицированному) DateTime (объекту), всегда (это и есть ваш вопрос: он подтверждает указанное поведение и противоречит вашему ожиданию, которое является неизменяемым вариантом, поскольку вам нужны конкретные данные для всех новых периодов каждый ).

hakre 07.11.2022 21:58

ср. DateTimeImmutable против DateTime

hakre 07.11.2022 22:06
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
2
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как предложил @MarkusAO в (теперь удаленном) комментарии, использование клона объектов помогло мне:

$newPeriod["start"] = clone end($newPeriods)["start"];
$newPeriod["end"]   = clone end($newPeriods)["end"];

Другие вопросы по теме