#php #php-7 #php-7.3 #php-7.4
Вопрос:
Во-первых, я новичок в английском языке, так что извините меня, если есть ошибки
2 класса DateTime и DateTimeImmutable реализуют один и тот же интерфейс DateTimeInterface. Поэтому я хочу знать :
- В чем разница между этими 2 классами DateTime и DateTimeImmutable ?
- Каковы варианты использования этих классов ?
Ответ №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. Точнее говоря, интерфейс не охватывает методы, которые допускают изменение состояния.
Вариант использования для выбора того или иного варианта в основном зависит от предпочтений, стандартов кодирования и, в некоторой степени, потребности в качестве кода и скорости разработки.