Время, которое можно изменить, по сравнению с временем

#php #php-7 #php-7.3 #php-7.4

Вопрос:

Во-первых, я новичок в английском языке, так что извините меня, если есть ошибки

2 класса DateTime и DateTimeImmutable реализуют один и тот же интерфейс DateTimeInterface. Поэтому я хочу знать :

  1. В чем разница между этими 2 классами DateTime и DateTimeImmutable ?
  2. Каковы варианты использования этих классов ?

Ответ №1:

Суть различия описана в документации DateTime класса:

Этот класс ведет себя так же, как и DateTimeImmutable, за исключением того, что объекты сами изменяются при вызове методов модификации, таких как DateTime::modify ().

Давайте понаблюдаем за этой разницей на конкретном примере:

 $date = new DateTime();
$tomorrow = $date->modify(' 1 day');
echo $date->format('Y-m-d');
echo $tomorrow->format('Y-m-d');
 

Это выведет:

 2021-05-15
2021-05-15
 

Здесь произошло то, что modify возвращен один и тот же экземпляр DateTime объекта. Переменная $tomorrow не содержит другого объекта, она содержит ссылку на исходный объект. Обновление новой переменной также изменило исходную переменную.

Если мы выполним ту же модификацию, но на неизменяемой версии:

 $date = new DateTimeImmutable();
$tomorrow = $date->modify(' 1 day');
echo $date->format('Y-m-d');
echo $tomorrow->format('Y-m-d');
 

Это выведет:

 2021-05-14
2021-05-15
 

Поскольку DateTimeImmutable методы модификации не возвращают один и тот же экземпляр , они дают вам новый экземпляр. Это также означает, что вы должны присвоить его результат переменной (как в предыдущем примере) для неизменяемой версии, чтобы использовать ее:

 $date = new DateTime('2021-05-14');
$date->modify(' 1 day');
echo $date->format('Y-m-d'); // 2021-05-15

$date = new DateTimeImmutable('2021-05-14');
$date->modify(' 1 day');
echo $date->format('Y-m-d'); // 2021-05-14; original is untouched
 

Из-за такого поведения неизменяемая версия практически всегда должна быть предпочтительнее изменяемой. Случайное изменение экземпляра даты, которую вы не хотели изменять, является довольно распространенной ошибкой.

Вы можете предпочесть изменяемую версию, чтобы избежать этапа назначения в ситуациях, когда вы можете надежно определить, что нет опасности ухудшения состояния вашего приложения, но это лучше всего оценить, как только вы твердо усвоите концепции.

Кроме того modify , следующие методы также рассматриваются как мутирующие:

  • add
  • sub
  • setDate
  • setISODate
  • setTime
  • setTimezone

Комментарии:

1. Это немного скрыто в документации , поэтому, возможно, полезно отметить, что Immutable->modify() возвращает новый неизменяемый объект. Таким образом, каждый последующий modify() новый объект также должен быть присвоен переменной. Мне потребовалось некоторое время, чтобы это выяснить.

Ответ №2:

Разница заключается в «неизменяемой» части, что означает, что после создания объекта он никогда не сможет измениться (вики для получения дополнительной информации). Это означает, что всякий раз, когда вы изменяете один и DateTime тот же экземпляр, он будет изменен, но DateTimeImmutable при изменении вместо него будет возвращен новый измененный экземпляр.

В общем случае неизменяемый объект никогда не изменит свое состояние после создания. Вместо этого, когда требуется изменение, он вернет новый экземпляр того же класса с измененным состоянием.

Тот факт, что они оба реализуют один и тот же интерфейс DateTimeInterface, немного сбивает с толку, но может быть объяснен тем фактом, что интерфейс не описывает все доступные функции, которые предлагают DateTime и DateTimeImmutable. Точнее говоря, интерфейс не охватывает методы, которые допускают изменение состояния.

Вариант использования для выбора того или иного варианта в основном зависит от предпочтений, стандартов кодирования и, в некоторой степени, потребности в качестве кода и скорости разработки.