Archive for the ‘lose Typisierung’ tag
PHP und die lose Typisierung
Heute mal eine sehr praktische Erfahrung:
Der Kollege nebenan fragte, ob ich mal kurz rübergucken kann, er verstehe die Ausgabe einer Funktion nicht. Vereinfacht sah der Code so aus (über Sinn und Unsinn soll hier nicht diskutiert werden, es ist nur vereinfacht dargestellt):
function show(array $headerArray) { foreach ($headerArray as $headerKey => $headerValue) { $outputString = $headerKey . ':'; foreach ($headerValue as $valueKey => $value) { if ($valueKey != 'append') { $outputString .= $value; } } return $outputString; } }
Die Funktion erwartet ein Array mit Header-Informationen. Diese sollen durchlaufen werden, und die Inhalte sollen als Wertepaare-String zurückgegeben werden, wenn der innere Key nicht „append“ ist.
Soweit ist der Code OK. Jetzt kommt der Aufruf:
$headerArray = array("From" => array( 0 => 'john.doe@some.city', 'append'=> true )); echo show($headerArray);
Wie lautet die Ausgabe? Korrekt, nämlich so:
From:
Wenn ich den Aufruf leicht ändere:
$headerArray = array("From" => array( '0' => 'john.doe@some.city', 'append'=> true )); echo show($headerArray);
Wir nutzen also als Key nun den String ‚0‘. Jetzt sollte das richtige rauskommen. Aber man liegt immernoch falsch:
From:
Da wurde ich stutzig. Man sollte denken, jetzt wird der String ‚0‘ mit dem String ‚append‘ verglichen. Da es ungleich ist, sollte die Email-Adresse ausgegeben werden. Falsch gedacht.
PHP scheint den Key eines Arrays als Integer zu casten wenn möglich. Egal ob wir 0 oder ‚0‘ als Key verwenden, beim Auslesen des Arrays erhalten wir immer einen Integerwert. Das sollte man sich auf der Zunge zergehen lassen.
Als Folge vergleicht er also immer den Integer 0 mit dem String ‚append‘. Damit ein Vergleich möglich ist, castet PHP den String korrekterweise als Integer, und das ergibt ja bekannterweise 0.
Das ursprüngliche Problem lag natürlich beim != . Man hätte das ganze vermeiden können, indem man !== verwendet, dann wäre das Problem nicht aufgetreten, und ich hätte einen Artikel weniger.