Добавление в качестве нового ответа вместо перефразирования / перефразирования старого.
Как прокомментировал @ Álvaro González на мой другой ответ, что объекты на многих языках ведут себя как-то что отличается от того, что мы думаем при передаче объектов между разными переменными.
Цитата из PHP. net
Один из ключевых моментов PHP 5 OOP часто упоминается, что «объекты по умолчанию передаются по ссылкам». Это не совсем так. Этот раздел исправляет эту общую мысль с помощью нескольких примеров.
Ссылка PHP - это псевдоним, который позволяет двум различным переменным записывать одно и то же значение. Начиная с PHP 5, объектная переменная больше не содержит сам объект как значение. Он содержит только идентификатор объекта, который позволяет средствам доступа к объекту находить реальный объект. Когда объект отправляется аргументом, возвращается или назначается другой переменной, разные переменные не являются псевдонимами: они содержат копию идентификатора, который указывает на тот же объект.
Объяснение : (что я могу понять из этого)
Если $var1
содержит объект, и вы пытаетесь инициализировать $var2
с помощью $var1
, используя оператор присваивания (=
), например, $var2 = $var1
, содержимое $var1
копируется (передается с помощью value ) в $var2
, но, как указано в руководстве, в случае $var1
, $var1
не содержит сам объект как значение , но простой идентификатор объекта, который , простыми словами, указывает на реальный объект . Таким образом, в случае вышеупомянутой инициализации идентификатор объекта в $var1
копируется (передается значением ) в $var2
, и теперь обе переменные $var1
, $var2
содержат значение, которое указывает на тот же объект, поэтому кажется, что присваивание действовало как переданное ссылкой , а не значением .
Итак, когда вы это делаете,
$splitdate = new DateTime('2010-12-31');
$holiday1end = $holiday2start = $splitdate;
Фактически вы копируете идентификатор объекта того же объекта в другие переменные. И поскольку вы sub
отслеживаете и add
используете одинаковое количество дней, все эти операции применяются к одному и тому же объекту. И кажется, что код не работает, однако он работает правильно.
Если вы сделаете что-то вроде ниже, вы заметите, что к дате добавляется 1 день (в основном вычитаются 2 дня, а затем 3 дня добавлено).
$date = '2010-12-31';
$splitdate = new DateTime($date);
$holiday1end = $holiday2start = $splitdate;
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P3D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 2: " . $holiday2start->format("Y-m-d")."\n";
Если вы разделите экземпляры объекта DateTime
, вы получите желаемый результат.
$date = '2010-12-31';
$splitdate = new DateTime($date);
$holiday1end = new DateTime($date);
$holiday2start = new DateTime($date);
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P2D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 1: " . $holiday2start->format("Y-m-d")."\n";
Рабочий пример приведенного выше кода
Пример с разницей в 1 день
Если вы хотите скопировать сам объект, вы можете использовать clone , что делает мелкую копию объекта . Итак, используя пример кода в вашем вопросе с clone
.
$date = '2010-12-31';
$splitdate = new DateTime($date);
// $holiday1end = clone $splitdate;
// $holiday2start = clone $splitdate;
// OR
// $holiday1end = clone $splitdate;
// $holiday2start = clone $holiday1end;
// OR in one line
$holiday2start = clone $holiday1end = clone $splitdate;
$holiday1end->sub(new DateInterval('P2D'));
$holiday2start->add(new DateInterval('P2D'));
echo "Holiday 1: ".$holiday1end->format("Y-m-d")."\n";
echo "Then " . $splitdate->format("Y-m-d")."\n";
echo "Holiday 2: " . $holiday2start->format("Y-m-d")."\n";
, вы получите желаемые результаты ( Пример ).