In meiner Programmiertätigkeit wechsle ich oft zwischen verschiedenen Programmiersprachen. Hat man erstmal Konzepte wie strukturierte und objektorientierte Programmierung verstanden, ist das auch gar nicht so schwierig. Probleme tauchen manchmal aber ausgerechnet bei ganz einfachen Dingen auf.
Strings in PHP zu vergleichen ist eigentlich einfach, gibt es doch den „==“ Operator. Doch es lauert eine Falle: Ist einer der beiden Operanden kein String, gibt es eine automatische Umformung. Und die kann auch schon mal anders sein, als man sich das vorstellt.
0 == „hallo“ liefert wahr, weil „hallo“ in eine Zahl mit dem Wert 0 umgewandelt wird. Brisant wird dies, wenn die 0 Rückgabewert einer Funktion war die normalerweise einen String liefert, und eine 0 z. B. im Fehlerfall. Wenn der Programmierer nicht darüber nachdenkt, so verhält sich das Programm anders als erwartet, und das ausgerechnet im Fehlerfall, der meist nicht so gut getestet wird.
Z.B.
$cmd = getCommandFromUser() if ($cmd == "deleteTable"){ deleteDatabaseTables(); |
In PHP gibt es noch den Operator mit drei Gleichheitszeichen, „===„. In PHP testet es zunächst, ob beide Operanden den gleichen Typ haben.
Diesen Operator kann man also in solchen Fällen nehmen. Nun halte ich die Gleichheitszeichen für alles andere als eingängig, die zwei Gleichheitszeichen sind ja eigentlich schon mathematisch fragwürdig. Der === Operator wird ja gerne in Sprachen genommen, wenn man irgendwie noch einen weiteren Vergleichsoperator benötigt, wobei die Semantik in jeder Programmiersprache verschieden ist…
Eine weitere Möglichkeit sind strcmp() und strcasecmp(). Das zweite bietet sich oft an, wenn die Groß/Kleinschreibung ignoriert werden soll. Vorsichtig muss man sein, weil die Funktionen 0 liefern, wenn die Strings gleich sind, in anderen Kontexten ist 0 ja als „False“ zu sehen. Der Code wird dadurch leider noch unübersichtlicher:
if (0 == strcasecmp($cmd, "deleteTable")){...} |
Heute ist eine Sicherheitslücke bekannt geworden, die auf dem beschriebenen Problem beruht. Im weit verbreiteten Contentmanagementsystem Typo-3 ist sind die Nebenwirkungen eines vermeintlich einfachen Vergleichs offenbar Jahre unentdeckt geblieben:
http://typo3.org/teams/security/security-bulletins/typo3-sa-2010-020/
Zwölf Jahre später ist ab PHP 8.0 diese Falle dann entschärft worden: Ein Vergleich wie 0==“deleteTable“ liefert jetzt wie erwartet „false“.