PHP 7.4 mit Typisierten Properties

Zeit für Klarheit!

Endlich kommen die typisierten Properties. Mit dem anvisierten Release von PHP 7.4 zum bekommen wir nach langer Zeit endlich die Möglichkeit auch die Properties einer Klasse typisiert anzugeben.

Seit PHP 5 kamen nach und nach mehr Möglichkeiten der klaren Typisierung für Funktionen.
Nun aber mit PHP 7.4 ist es endlich dann auch soweit, dass wir Klassen Properties klar typisieren können.
Folgende Typen sind dazu nutzbar:

  • bool
  • int
  • float
  • string
  • array
  • iterable
  • object
  • self
  • Klassen

Sehen wir uns folgendes Beispiel mal an.
Aktuell würden wir eine Klasse wie folgt definieren wenn wir klare Typendefinition sicherstellen möchten:

<?php
class SomeClass {
    private $someString;
    private $someBool;

    public function setSomeString(?string $someString): self {
        $this->someString = $someString;
    }

    public function getSomeString(): ?string {
        return $this->someString;
    }

    public function setSomeBool(bool $someBool): self {
        $this->someBool = $someBool;
    }

    public function getSomeBool(): bool {
        return $this->someBool;
    }
}

Das Equivalent hierzu in PHP 7.4 wäre:

<?php
class SomeClass {
    public ?string $someString;
    public bool $someBool;
}

Wir sparen uns durch die Typendeklaration die getter und setter, falls diese keine Logik beinhalten müssen.

Im obigen Beispiel ist $someBool nicht initialisiert und hat intern den Wert "null" was bei einem direkten Zugriff auf $someBool ohne vorherige Initialisierung zu einem Fatal Error (\Error Exception) führen würde. Lediglich der Zugriff auf $someString wäre in diesem Falle valide, da durch das "?" angegeben ist, dass $someString auch "null" sein darf. Man kann aber auch mit isset() prüfen ob eine Property initialisiert wurde.

Nun können wir die Propeties der Klasse mit den dem deklarierten Typen entsprechenden Daten initialisieren und auch nur dann abrufen.
Der Zugriff erfolgt wie bisher auch ganz normal auf die Properties:

<?php
class SomeClass {
    public string $someString;
    public bool $someBool;
    public \DateTime $someDateTime;
    public ?float $someFloat;
}

$someClass = new SomeClass();

$someClass->someString = 'Hello typed property!';
$someClass->someBool = true;
$someClass->someDateTime = new \DateTime();
$someClass->someFloat = 123.45;
Wo die Initialisierung der Properties genau geschieht ist irrelevant. Das heißt man könnte diese auch in der Klasse im Konstruktor oder einer anderen Methode initialisieren. Wichtig ist lediglich, dass diese vor dem Zugriff initialisiert wurden.

Man kann die Variablen natürlich auch im normalen Programmfluss auch deinitialisieren. Dies kann man durch die unset() Methode erreichen.
Das nutzen der Methode führt dazu, dass die variable wieder in den nicht initialisierten Zustand gebracht wird. Heißt der wert wird auf "null" gesetzt.
Properties auf die nach einer Deinitialisierung wieder zugegriffen wird - wenn diese nicht nullable sind - werden dann wieder den oben erwähnten Fatal Error werfen.

Dieses Beispiel zeigt solch einen Fatal Error Fall:

<?php
class SomeClass {
    public string $someString;
}

$someClass = new SomeClass();
$someClass->someString = 'someString';
var_dump($someClass->someString);
// Output: string(10) "someString"

unset($someClass->someString);

var_dump($someClass->someString);
// Output: Fatal error: Uncaught Error: Typed property SomeClass::$someString must not be accessed before initialization

Eine weitere Sache die es zu beachten gilt: ähnlich wie es zuvor bei typisierten Gettern und Settern war, kann man natürlich nicht den falschen Daten-Typen an die Property setzen. Somit kann einer als "bool" deklarierte Property beispielsweise kein Objekt des Typen \DateTime übergeben werden, da dies zu einem TypeError führt.

Bitte beachtet, dass z.B. eine als string deklarierte Property im nicht aktiven strict_types Fall, fast jeden übergeben Wert annehmen kann der implizit zu einem string gecastet werden kann. Dies gilt auch für Objekte die die __toString() Methode implementieren.

Folgendes Beispiel dazu:

<?php
class SomeClass {
    public string $someString;
}

class SomeOtherClass {
    public function __toString(): string {
        return 'toString';
    }
}

$someClass = new SomeClass();
$someOtherClass = new SomeOtherClass();

$someClass->someString = $someOtherClass;
var_dump($someClass->someString); // Output: string(8) "toString"

Dies ist im nicht strict_types Modus völlig valide.

Somit solltet Ihr nun etwas Überblick wie die Typed Properties eingesetzt werden können und wie Ihr es nutzen könnt um euren Code übersichtlicher und einfacher zu gestalten.

Ismail Özgün Turan am

Kommentare 0