2014-11-04 15 views
5

widziałem ten mały kawałek kodu, który uchyla moje rozumienie:Zrozumienie PHP Rodzaj Przymus

<?php 

$a = '0e462097431906509019562988736854'; 
$b = '0e830400451993494058024219903391'; 

var_dump($a == $b); 

który wyjściowa:

bool(true) 

Rozumiem, że podczas korzystania == PHP spróbuje rozmytej porównania konwersja cicha pomiędzy typami w celu przeprowadzenia porównania. Nie rozumiem, dlaczego rozumiem, że PHP wydaje się uważać, że te dwa ciągi są takie same. Pomyślałbym, że od $a i $b są ciągi, że konwersja typu nie będzie musiała mieć miejsca.

Czego nie rozumiem?

Odpowiedz

4

Myślę, że ten artykuł wyjaśnia to całkiem dobrze:

Type-coercing comparison operators will convert numeric strings to numbers

Wystarczy zacytować główny problem tutaj:

Według php language.operators.comparison operatorzy porównania Typ-zmuszaniu będzie zmusić oba operandy do pływaków, jeśli oboje wyglądają jak liczby, nawet jeśli są one zarówno już ciągi:

gdzie zarówno strings są za pomocą notacji wykładniczej, dlatego są traktowane jako ciągi znaków numerycznych, dzięki czemu luźne porównanie (==), zmuszania ich strings do floats zanim faktycznie „luźno” porównując je.

Jako najlepszych praktyk oraz w celu zapobieżenia nieoczekiwane zachowanie, zawsze staraj się używać identity equality (===) szczególnie w kontaktach z strings

0

To naprawdę nie jest odpowiedzią, ale jeśli spróbujesz:

$a = '0e4620974319065090195629887368549'; 
$b = '0e8304004519934940580242199033918'; 
echo floatval($a) . '<br>' . floatval($b);var_dump($a == $b); 

Otrzymasz:

bool (true)

Teraz jeśli próbujesz:

$a = '0e4620974319065090195629887368549'; 
$b = '1e8304004519934940580242199033918'; 
echo floatval($a) . '<br>' . floatval($b);var_dump($a == $b); 

Otrzymasz:

INF

bool (false)

Domyślam się, że PHP konwertuje ciągi do pływaków i daje wynik porównania przy użyciu pływaków, który następnie i tak nie są poprawne, ale to już inna historia.

+0

Ale dlaczego, kiedy oba są łańcuchami? – amphetamachine

0

W oficjalnej dokumentacji, badanie równości betwen 2 vairiables jest następująca:

$a == $b # Equal TRUE if $a is equal to $b after type juggling. 

Przykład:

$a = 13; # integer type 
$b = "13"; # string type 
var_dump($a == $b); # will say TRUE, because juggling was made 
var_dump($a === $b); # will say FALSE, because PHP will also evaluate the type of variables :) 
0

PHP próbuje konwertować do typu float, ponieważ ciąg rozpoczyna się od 0. zatrzymuje się po 0, ponieważ następny znak nie jest liczbą. To samo dzieje się, gdy używasz przymusu do konwersji notacji naukowej na liczbę całkowitą:

$x = (float)"12E-1x"; // $x == 1.2 
$x = (int)"12E-1x"; // $x == 12 (stops at E because it's not an integer)