Lerne Coding
PHP 8 - Union Types, mehrere Typen angeben
29.12.2020

PHP 8 - Union Types

Inhaltsverzeichnis
[[TABLE OF CONTENTS]]
access_timeGeschätzte Lesezeit ca. Minuten

Seither ist PHP dynamisch typisiert, das bedeutet, wenn du eine Variable definierst oder überschreibst, ermittelt PHP daraus den benötigten Datentyp. Dadurch entstehen aber Probleme: Es wird jedes Mal Rechenzeit verschwendet, um den Datentypen zu ermitteln und du könntest versehentlich Datentypen übergeben, welche die Funktion gar nicht verarbeiten kann. Ein PDO-Objekt in eine Datumsfunktion zu übergeben, ist nicht die klügste Idee. Leider wird so was nicht weiter geprüft und es kann deshalb zu Fehlern führen.

Das Konzept der Typisierung in Java

In Java hat man von Anfang an fest definierte Datentypen. Wenn die Variable eineZahl also als Integer definiert wurde, musst du sie erst aus dem Speicher löschen, bevor du daraus einen String machen kannst. Zwar gibt es auch seit Java 11 den Datentypen var, aber dieser erkennt nur den Datentypen deiner aktuellen Variable und typisiert diese statisch. Wenn eineZahl also der Wert 10 zugewiesen wird, ist sie ein Integer.

Statische Typisierung in PHP 7.4

In PHP 7.0 bis 7.4 hatte man sich zunächst dazu entschieden, zu vermerken, welchen Datentyp eine Variable haben soll. Man konnte diesen aber nicht verbindlich machen und so konnten weiterhin falsche Datentypen übergeben werden. Ab PHP 7.4 wurde die optionale statische Typisierung eingeführt. Man konnte also einen Datentypen angeben, aber falls nicht, wurden diese weiterhin dynamisch ermittelt. Jedoch stürzt nun ein Programm ab, wenn eine Funktion falsche Datentypen erhält, die sie nicht verarbeiten konnte. Nun konnte man sehen, wann die Funktion falsche Datentypen erhielt und es wurden keine Operationen ausgeführt, welche das System zum Einstürzen bringen konnten.

Union Types in PHP 8

Mit PHP 8 hat man jedoch gemerkt, dass eine Funktion manchmal mehrere Datentypen für einen Parameter akzeptieren kann. So könnte ein Datum zum Beispiel ein Unix Timestamp (Integer), ein Datetime-String (String) oder ein DateTime-Objekt sein. Bis dato konnte man aber den Datentypen bei solchen Funktionen nicht angeben und er musste weiterhin in der Funktion validiert werden. PHP 8 hat es sich deshalb zur Aufgabe gemacht, mehrere statische Datentypen zu akzeptieren. Diese sind die sogenannten "Union Types". Solltest du Union Types selbst ausprobieren wollen, lies gerne meinen "PHP 8 auf Linux" Artikel, in dem ich erkläre, wie du PHP 8 installieren kannst (zum aktuellen Zeitpunkt ist PHP 8 noch sehr neu). Ich möchte dir nun ein Beispiel zu Union Types geben:

/*
    getGermanDateString erstellt aus einem Unix Timestamp, Datumsstring 
    oder Datetimeobjekt ein deutsches Datum
*/
function getGermanDateString (int|string|Datetime $date) {
    if (gettype($date) === "integer") {
        return date("d.m.Y", $date);
    } elseif (gettype($date) === "string") {
        return date("d.m.Y", strtotime($date));
    } else {
        return $date->format("d.m.Y");
    }
}

echo getGermanDateString(time());
// output: 12.12.2020
echo getGermanDateString("12.08.2016");
// output: 12.08.2016
echo getGermanDateString(date_create('2008-01-01'));
// output: 01.01.2008
echo getGermanDateString(array("12.09-2022"));
/* output: PHP Fatal error:  Uncaught TypeError: getGermanDateString(): Argument #1 ($date) must be of type Datetime|string|int, array given, called in /home/uvulpos/Desktop/(...)/file.php on line 16 and defined in /home/uvulpos/Desktop/(..)/file.php:3
Stack trace:
#0 /home/uvulpos/Desktop/(...)/file.php(16): getGermanDateString()
#1 {main}
  thrown in /home/uvulpos/Desktop/(...)/file.php on line 3
*/

Akzeptierte Datentypen

Um den Datentypen angeben zu können, musst du wissen, welche Datentypen es gibt. Ich habe dir hier die wichtigsten aufgelistet:

Thema der Tabelle "PHP Datentypen "
Typ Bedeutung
mixed Aktueller Standard (jeglicher Datentyp kann übergeben werden)
array Listen (eindimensional und mehrdimensional)
iterable Ein Objekt, das mit foreach durchgezählt werden kann
string Texte; alphanumerische Zeichenketten
integer Ganzzahlen
float Gleitkommazahlen
boolean Wahrheitswert (true / false) → es kann auch true oder false als Datentyp angegeben werden als Abkürzung, wenn beim boolean nur true oder false zurückkommt (zur Übersicht)
callable Funktionsnamen oder anonyme Funktionen
object Datenobjekte
(instances) Klassenname der jeweiligen Klasse oder Interface. Es können Objekte dieser Klasse übergeben werden.

Datentyp für Rückgabewerte

Man kann auch angeben, welcher Datentyp der Rückgabewert einer Funktion hat. Auch dieser darf wieder aus verschiedenen Typen bestehen, z.B. aus String und false. Nehmen wir hierzu unser Beispiel von eben zur Hilfe:

function getGermanDateString (int|string|Datetime $date): string|false {

Union Types in frühere Versionen reimplementieren

Solltest du Union Type Checks in alte PHP Versionen einbauen wollen, da du die Version beispielsweise nicht aktualisieren kannst oder darfst, kannst du dir diese Abfrage sehr leicht selbst schreiben. Ich habe dazu PHP 7.4 benutzt, du kannst es aber auch für ältere PHP Versionen einbauen. Bitte beachte, dass dieses Beispiel noch optimiert werden kann, es wurde zur Veranschaulichung geschrieben.

function validateType($var, $datatypes) {

    // Datentyp-Pattern muss ein String sein
    if (gettype($datatypes) != "string") 
    { return false; }

    // Trenne die gültigen Datentypen
    $datatypes_array = explode("|", $datatypes);

    // Überprüft ob der Datentyp gültig ist
    foreach ($datatypes_array as $key => $datatype) {
        if (gettype($var) === strtolower(trim($datatype))) { return true; }
    }
    return false;
}

echo "String: ".validateType(10, "string|integer|array");

Fazit

Statische Datentypen sind praktisch, um zu wissen, welche Datentypen eine Funktion verarbeiten kann. Sie verhindern Fehler und erhöhen intern die Geschwindigkeit von PHP. Zudem können auch mehrere Datentypen definiert werden, man hat also die volle Kontrolle über seinen Code. Ich werde Union Types künftig nutzen und freue mich schon auf die ersten Entwicklungen damit.

Kommentare zum Artikel

Es sind noch keine Kommentare vorhanden? Sei der/die Erste und verfasse einen Kommentar zum Artikel "PHP 8 - Union Types, mehrere Typen angeben"!

Kommentar schreiben

Vom Autor Empfohlen
close