Verwenden Sie datetime nicht mehr

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')); //2019-06-30 10:03:00 var_dump($finishedAt->format('Ymd H:i:s')); //2019-06-30 10:03:00 

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')); //2019-06-30 10:00:00 var_dump($finishedAt->format('Ymd H:i:s')); //2019-06-30 10:03:00 

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.

Source: https://habr.com/ru/post/de464253/


All Articles