Haladó PHP: kb. '1' == '2' ...parser bug?
<?php
$s1 = '00050003000500000008000100000000';
$s2 = '00050003000500000008000200000000';
var_dump((string)$s1 == (string)$s2? 'y' : 'n');
?>
Ez Ubuntu Linux alatt, 5.3.5-ös PHP-val fordult elő (semmi extra modul, hacsak az xdebug annak nem számít). Érdeklődve kérdezem: elmagyarázná valaki, hogyan lehetséges ez?
Megjegyzés: ez a kimenet felvet bizonyos kérdéseket azért az MD5 hash-ek összehasonlításakor is...
A konkrét feladatban egyébként arra lenne szükségem, hogy a két stringből melyik a "kisebb" és melyik a "nagyobb", vagy persze adott esetben egyenlőek-e. Verziószámokat szeretnék ellenőrizni úgy, hogy a fentihez hasonló normál alakra hozom őket, elkerülve azt, hogy külön erre a problémára egy osztályt kelljen írnom és implementálni kelljen minden komparáló operátorra egy metódust.
Előre is köszi a segítséget!
strcmp
számok vs string
==
operátor valószínűleg előbb számmá alakítja a stringet, ami így egyenlőnek fog tűnni. Használj helyette===
-tÍgy van, mivel ezek numerikus
Update: Itt a végén hülyeséget írhattam, ez inkább (int)$1 == (int)$2 lesz, és mivel túlléped az int max értékét, azért lesz egyenlő (ilyenkor megkapja mind2 változód a max int értéket). Azért is gondolom így, mert float esetében elég furcsa lenne, ha egyenlőségre jutna a kiértékelés (megzavart kicsit a dolog, mert fura hogyha átlépi a max int értéket a változó, akkor nem kasztolódik floatra)
Nem írtál
Lásd:
php > $n="100000000000000000001000000000000001000000000000";
php > print $n+0;
1.0E+47
Csakhát a float sem végtelen pontosságú, így floatra konvertálva is kaphatsz azonos értéket.
Bővebben itt: float
mas is
http://www.mail-archive.com/internals##kukac##lists.php.net/msg50082.html
szerintem egy bugot lehetne nyitni neki, nem latom, hogy azonos string tipusu valtozok osszehasonlitasanal miert tortenik type jugling.
Tyrael
Hogy a működése hülyeség,
Example Name Result
$a == $b Equal TRUE if $a is equal to $b after type juggling.
Az == operátor így működik.
Bővebben: operators
A doksi is azt javasolja, amit Poetro írt: === a == helyett (csak valamivel határozottabban :-) )
ui: a linked egy 404-es hibára visz. (bár gyanús a ##kukac## :-) )
a link nalam mukodik. igazad
igazad van, dokumentalt viselkedes:
illetve lasd peldak.
Tyrael
Nálam le van tiltva a JS. Azt
ettol fuggetlenul szerintem
tovabbi problemas esetek:
"-0" == "+0" // true
"0" == "0x00" // true
amugy levlistan volt mar korabban szo, hogy az ilyen implicit type castolasbol eredo adatveszteseknel dobhatna a php egy E_TYPE tipusu hibat.
lehet, hogy felelesztem a temat.
Tyrael
A PHP kezdőbarát nyelv
Köszi a válaszokat, ilyen
Akkor strcmp()-t fogok használni, a kisebb és nagyobb összehasonlításhoz úgyis megfelel. Float-ra egyébként pont a pontatlanság miatt nem akartam konvertálni, szívesen konvertálnám át én ezt int-re persze, de ekkora drabál int-et a PHP nem kezel. Marad az strcmp() tehát és köszi a tippet.
Az egyébként kicsit nonszensz azért, hogy hiába határozom meg a típusát a két stringnek, csak mert a parser má' pedig jobban tudja...
Köszi mégegyszer!
A === használatát már
Esetleg megoldás lehet ez is, ha ragaszkodsz a == használatához:
"X$valt1"=="X$valt2"
utolsó megoldás azért már
Tyrael
Nem kicsit. :D Tudnád, hogy
Tudnád, hogy meglepődtem, amikor kipróbáltam és működött! ;-)
Ez az X-es ötlet nagyon állat
Egyébként: PHP-ben 4 óta létezik strict-egyenlő, vajon miért nem létezik strict-kisebb és strict-nagyobb is?
Köszi mégegyszer az ötletet, frenetikus :)
Eszerint linux/unix shell
(merthogy az ötlet onnan jött, ahogy Tyrael is említette)
Az ===-vel kapcsolatos problémáidat nem teljesen értem, de PHP-ben (is) erősen kezdő szinten állok.
Nem, *ix shell script-eket
Egyébként: PHP-ben 4 óta
Mert azt mondani van értelme, hogy ha a és b különböző típusúak, akkor nem egyenlőek, de annak, hogy ha különböző típusúak, akkor b a nagyobb, nem igazán...
Logikus, ugyanakkor szerintem
=== esetén is az első vizsgálat az argumentumok típusa, és csak azt követi az értékek azonossága. Ugyanez miért lenne értelmetlen ebben a sorrendben bármelyik másik komparáló operátor esetében?