Speziell für Studenten des Backend Developer in PHP- Kurses haben sie eine Übersetzung eines interessanten Artikels über die Nebenwirkungen eines beliebten Tools vorbereitet.
Das Arbeiten mit Datum und Uhrzeit in PHP ist manchmal ärgerlich, da es zu unerwarteten Fehlern im Code führt:
$startedAt = new DateTime('2019-06-30 10:00:00'); $finishedAt = $startedAt->add(new DateInterval('PT3M')); var_dump($startedAt->format('Ymd H:i:s'));
Sowohl die Funktionen
$startdate
als auch
$finishdate
es drei Minuten lang eilig, da Methoden wie
add ()
,
sub()
oder
modify()
auch das DateTime-Objekt ändern, für das sie aufgerufen werden, bevor sie zurückgegeben werden. Das obige Beispiel zeigt natürlich unerwünschtes Verhalten.
Wir können diesen Fehler beheben, indem wir das Objekt, auf das verwiesen wird, kopieren, bevor wir mit ihm interagieren. Beispiel:
$startedAt = new DateTime('2019-06-30 10:00:00'); $finishedAt = clone $startedAt; $finishedAt->add(new DateInterval('PT3M'));
Jedes Mal, wenn ich auf einen Klon in PHP-Code stoße, riecht es nach einem Hack der fehlgeschlagenen Codearchitektur von jemandem. In diesem Fall haben wir das Klonen verwendet, um Verhaltensänderungen zu vermeiden. Gleichzeitig wurde der Code hässlich und verursachte viel unnötiges Rauschen.
Alternativ kann das Problem behoben werden, indem die ursprüngliche
DateTime
Instanz in
DateTimeImmutable
:
$startedAt = new DateTime('2019-06-30 10:00:00'); $finishedAt = DateTimeImmutable::createFromMutable($startedAt)->add(new DateInterval('PT3M'));
Warum nicht
DateTimeImmutable
von Anfang an verwenden?
Kompromisslose Verwendung von DateTimeImmutable
Anstatt Sicherheitsmethoden manuell anzuwenden, um unerwartete Änderungen beim Übergeben von Datums- /
DateTimeImmutable
zu verhindern, verwenden Sie
DateTimeImmutable
, das Methoden kapselt und Ihren Code zuverlässiger macht.
$startedAt = new DateTimeImmutable('2019-06-30 10:00:00'); $finishedAt = $startedAt->add(new DateInterval('PT3M')); var_dump($startedAt->format('Ymd H:i:s'));
In den meisten Fällen wird das Konzept eines Datums als Wert betrachtet. Wir vergleichen die Daten anhand ihrer Werte. Wenn wir das Datum ändern, wird es zu einem anderen Datum. All dies korreliert perfekt mit dem Konzept des
Wertobjekts , und eines der wichtigen Merkmale von Wertobjekten ist, dass sie unveränderlich sind.
Detaillierter Codierungsstil
Die Unveränderlichkeit zwingt Sie dazu, ein
DateTimeImmutable
Objekt bei jeder Interaktion explizit neu
DateTimeImmutable
, da es seinen Wert nie ändert und stattdessen eine Kopie
DateTimeImmutable
. Nach vielen Jahren der Arbeit mit DateTime und da Mutabilität in vielen wichtigen Programmiersprachen die Standardeinstellung ist, ist es schwierig, die Gewohnheit, sie zu verwenden, loszuwerden und sich an den neuen Schreibstil anzupassen, der das Remapping fördert:
$this->expiresAt = $this->expiresAt->modify('+1 week');
Statistische Analysetools wie
PHPStan und
eine seiner Erweiterungen können uns warnen, wenn wir die Zuweisung weglassen und
DateTimeImmutable
falsch verwenden.
Eine solche kognitive Neigung zur Variabilität wird jedoch unterdrückt, wenn wir arithmetische Operationen an den Werten von Grundelementen durchführen, zum Beispiel:
$a + 3;
. An sich wird dies als bedeutungslose Aussage wahrgenommen, der eindeutig eine Neuzuweisung fehlt:
$a = $a + 3;
oder
$A += 3;
. Es wäre cool, so etwas bei Wertobjekten zu verwenden, oder?
Einige Programmiersprachen verfügen über syntaktischen Zucker, der als
Operatorüberladung bezeichnet wird. Auf diese Weise können Sie Operatoren in benutzerdefinierten Typen und Klassen implementieren, sodass sie sich wie primitive Datentypen verhalten. Es würde mir nichts ausmachen, wenn PHP diesen Trick aus einer anderen Programmiersprache entlehnt hätte, und wir könnten wie folgt schreiben:
$this->expiresAt += '1 week';
Einmalige Berechnungen
Einige Leute argumentieren, dass es in Bezug auf die Leistung besser ist,
DateTime
zu verwenden, da die Berechnungen innerhalb desselben Ausführungsbereichs durchgeführt werden. Dies ist jedoch akzeptabel, wenn Sie nicht Hunderte von Vorgängen ausführen müssen und sich daran erinnern, dass Links zu alten
DateTimeImmutable
Objekten vom Garbage Collector erfasst werden. In den meisten Fällen ist der Speicherverbrauch in der Praxis kein Problem.
Datums- / Zeitbibliotheken
Carbon ist eine äußerst beliebte Bibliothek, die die Datums- / Uhrzeit-API in PHP um einen umfangreichen Funktionsumfang erweitert. Genauer gesagt erweitert es die API der veränderlichen
DateTime
Klasse, deren Verwendung dem Thema dieses Artikels widerspricht.
Wenn Sie gerne mit Carbon arbeiten, aber Unveränderlichkeit bevorzugen, sollten Sie sich mit
Chronos vertraut machen. Dies ist eine eigenständige Bibliothek, die ursprünglich auf Carbon basierte und besonderes Augenmerk auf die Bereitstellung unveränderlicher Standardobjekte für Datum und Uhrzeit legt. Sie enthält jedoch auch veränderbare Optionen für den Fall, dass dies erforderlich ist.
Bearbeitet (07/05/2019): Es stellte sich heraus, dass Carbon eine unveränderliche Datums- / Zeitoption hat, was ein großes Plus ist. Der Grund, warum ich Chronos bevorzuge, ist jedoch, dass es im Gegensatz zu Carbon die Standardveränderlichkeit sowohl im Code als auch in der Dokumentation fördert und fördert. Dies sind entscheidende Faktoren im Kontext dieses Artikels.
Letzter Gedanke
DateTimeImmutable
wurde erstmals in PHP 5.5 eingeführt, aber zu meiner Überraschung entdecken es gerade viele Entwickler. Verwenden Sie
DateTimeImmutable
nach Möglichkeit standardmäßig, aber denken Sie daran, dass einige der Kompromisse, über die ich gesprochen habe, meiner Meinung nach eher eine Gewohnheitssache und eine Änderung der Denkweise sind.
Das ist alles. Traditionell warten wir auf Ihre Kommentare, Freunde.