Was macht eigentlich PHP ’s strict_types?

Mittlerweile gehört es in meinem Code zum Standard, dass ich den Strict Type Mode aktiviere. Ich denke nicht mehr drüber nach, wozu es da ist und was diese erste Zeile Code in PHP eigentlich macht. Moment mal? Was macht eigentlich PHP ’s strict_types?

Wir reden heute über Typensicherheit. Typensicherheit war vor PHP 7 einfach nicht oder nur mit sehr viel Aufwand darstellbar. Zudem bietet PHP nach wie vor eine sehr dynamische Typen Umwandlung, welche ich im folgenden Beispiel einmal verdeutlichen möchte.

<?php
$string = "42"; // $string ist ein String
$int = 42; // $int ist ein Integer

$what = $string * 1; // Integer 42 * 1
$ergebnis = $string + $int; // Integer 84

$int = $int * "1 kleinen Marcel" // Integer 42 * 1
$int = "foo"; // String

Seht ihr was ich meine? Numerische Strings werden in numerische Werte gewandelt. Man spricht hier von Type Juggling. Für simpelste Anwendungen ist das in Ordnung. Allerdings gibt man damit einen großen Teil an Kontrolle einfach an PHP ab. Vielleicht möchte ich gar nicht mit Strings rechnen? Vielleicht bestehe ich einfach darauf lediglich mit Integer und Float Werten rechnen zu können? Dieses Vorgehen ist okay, aber sehr unsauber.

Wie eingangs erwähnt, ist PHP seit der Version 7 in der Lage skalare Typen als Type Hints anzugeben. Skalare Typen sind integer, float, string und boolean Werte. Ein großer Schritt in Richtung Typensicherheit. Ich kann also angeben, welche Werte ich erwarte.

<?php
function addiereFloatUndInt(float $a, int $b): int
{
    return $a + $b;
}

$result = addiereFloatUndInt('2', 1.8);

// $a wird von string(2) zu float(2.0) geändert
// $b wird von float(1.8) zu int(1) geändert
// $result ist int(3)

Das erwartet man ja eigentlich so nicht. Aber PHP ist wegen seines Type Jugglings einfach so. Es wandelt die angegebenen Werte in die Werte, die ich in meiner Funktion haben möchte. Das ist nett, aber führt im schlimmsten Fall zu falschen Ergebnissen. Man muss sich nur mal ein Kassensystem vorstellen, welches so programmiert wurde. Katastrophe!

Genau hier setzt der strikte Umgang mit Typendeklarationen an. Sobald ich einen strikten Umgang mit Typen definiere, verlangt PHP, dass ich auch genau die Typen liefere, die in der Funktion definiert sind.

<?php
declare(strict_types=1);

function addiereFloatUndInt(float $a, int $b): int
{
    return $a + $b;
}

try {
    $result = addiereFloatUndInt('2', 1.8); // TypeError
    $result = addiereFloatUndInt(2, '1.8'); // TypeError
    $result = addiereFloatUndInt(2, 1.8); // float(3.8)
    $result = addiereFloatUndInt(1.8, 2); // float(3.8)
} catch (TypeError $error) {

}

Jetzt funktioniert die Addition so, wie ich es auch erwarte. Kein unerwünschtes Type Juggling, sondern die strikte Angabe von Werten, die auch den verlangten Typen entsprechen. Das declare Statement muss immer an erster Stelle in einer Datei deklariert werden. Leider gibt es noch keine globale Deklaration zum declare Statement. Man muss es also in jeder Datei notieren.

Warum ist das wichtig?

Nun haben wir gesehen, was der strikte Umgang mit Typen bewirkt. Aber warum ist das so wichtig? Weil Type Hints und strikte Typisierung einen Entwickler dazu zwingen genauer zu programmieren und es werden zwangsläufig Fehler vermieden. In anderen Worten: Es wird einfach sehr viel genauer gearbeitet. Ein positiver Nebeneffekt ist die leichtere Lesbarkeit von Code. Im Grunde genommen schreiben wir direkt selbstdokumentierenden Code, weil man in diesem Fall auch ohne die beschreibenden Doctype Blöcke auskommt. Man sieht sowohl die Typen von Parametern als auch Return Types direkt im Code.

PHP ’s loser Umgang mit Werten bleibt aber weiterhin erhalten. Sobald ich kein declare(strict_types=1); in meine PHP Dateien schreibe, bleibt es beim Type Juggling. Aus historischen Gründen ist das auch gut so.

Ich persönlich bin der Meinung, dass man für Code, der heute geschrieben wird, die strikte Typisierung voraussetzen sollte. Sie birgt aus meiner Sicht nur Vorteile. Was meint ihr? Wie sind Eure Erfahrungen mit dem Umgang mit Type Hints und strikter Typisierung?

Kommentar verfassen

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.