neunzehn83.de

Ein Mann, ein Blog, kein Plan.

PHP: gleich oder nicht gleich?

PHP ist schwach typisiert. Und das ist im Prinzip auch gut so! Dennoch passieren dadurch teilweise wirklich sonderbare Dinge:

"2d3" != "02d3"

Das ist einfach: Strings unterschiedlicher Länge können niemals gleich sein.

Aber:

"2e3" == "02e3"

Was läuft hier anders? Beim einfachen Vergleich ("==") versucht PHP zuerst jeden String als Zahl zu interpretieren. Das gelingt im ersten Beispiel offensichtlich nicht, wohl aber im zweiten: "2e3" wird als wissenschaftliche Notation (2 mal zehn hoch 3)  interpretiert und somit zur Zahl. Da bei Zahlen führende Nullen irrelevant sind, wird auch "02e3" zur Zahl. Man könnte also genauso gut "2e3" == 2000 schreiben.

Leider ist das mit den führenden Nullen nicht immer so:

"0012" != 0012

Hier kommt eine weitere Eigenschaft von PHP ins Spiel: Zahlen, die mit einer Null beginnen werden von PHP als Oktalzahl interpretiert. Nicht aber in Strings! Somit wird "0012" zu 12(dec) und 0012 zu 12(oct).

Da die internen Konvertierungen und Interpretationen von PHP nicht immer offensichtlich sind, empfiehlt es sich, in gewissen Situationen den "==="-Operator (strikter Vergleich) zu verwenden. Dieser ergibt nur dann True, wenn auch die Variablentypen (int, string, ..) auf beiden Seiten übereinstimmen. Beim "==="-Operator findet niemals eine Konvertierung statt.

"2e3" !== "02e3"

Das macht Sinn. Aber auch hier gibt es Überraschungen:

2e3 !== 1000

Hmm..

echo gettype(2e3); // double

Aha!  Zahlen mit Exponentialdarstellung sind immer vom Typ double. Liegt wohl daran, dass man damit auch sehr kleine Zahlen darstellen kann ($angstrom = 1e-10;). Also gilt:

2e3 === 1000.0

Dieses Spiel ließe sich beliebig fortsetzen. Dennoch: die gezeigten Verhaltensweisen sind so gewollt und auch Dokumentiert. Diese Extremfälle zeigen lediglich, wie gefährlich (weil schwer nachvollziehbar/erkennbar) manchmal ein scheinbar einfacher Vergleich in PHP sein kann.

Geschrieben am Samstag, 23. Januar 2010 und abgelegt unter Webtechnik.