2011-01-20 13 views
8

Czy $a == $b jest zawsze równoznaczne z $b == $a?Czy wszystkie porównania równości PHP są symetryczne?

Myślę, że w JavaScript istnieje kilka dziwnych przypadków, w których to nie jest prawdą, z powodu przesyłania.

Myślę, że ide jest poprawny. Zapytam kolejnego question.

+2

Powiedziałbym "refleksyjny". – Joe

+0

@Joe: Dzięki. Zaktualizowano. – mpen

+1

@Joe jest poprawne. Jest to uważane za _refleksyjność_. Skojarzenie jest wtedy, gdy '(A + B) + C = A + (B + C)' – treeface

Odpowiedz

3

Zależy od tego, co dzieje się między tymi dwoma połączeniami. W przeciwnym razie są one takie same. Zamówienie nie robi różnicy. Użycie 2 równa się == Łańcuch 1 i liczba całkowita równa 1, zwrócą wartość true w porównaniu. Typ jest ignorowany, porównywana jest tylko wartość. Więc nie ma dziwności.

http://php.net/manual/en/language.operators.comparison.php

<? 

$a=(string) 1; 
$b=(int) 1; 

var_dump($a); 
var_dump($b); 


echo $a==$b; 

Wyjścia: 1

http://www.ideone.com/JLJWQ

EDIT

celu wyjaśnienia, nie ma absolutnie nic nie można jeszcze umieścić w $ a lub $ b, aby uzyskać inny wynik porównania, po prostu umieszczając go po drugiej stronie operatora.

$a="1234"; 
$b="1234"; 

echo $a==$b; 
echo $b==$a; 

Wyjście, że dla dowolnego $ a lub $ b wartości, zawsze będzie bez wątpienia być true true lub false.

+1

Tak, ale to prosty przykład. Pomyślałem, że może były jakieś dziwne przypadki, takie jak "01" == 1 "1 może zostać przekonwertowany na ciąg, a następnie nie będą one równe, ale w' 1 == "01" 'ciąg znaków zostanie przekonwertowany na int, a następnie będą równe. Wiem, że tak nie jest. http://www.php.net/manual/en/language.types.string.php#language.types.string.conversion Ale może są jakieś dziwne, o których nie wiem. – mpen

+0

cóż .. jest jeden rodzaj dziwaczny, który jest wspomniany w komentarzach. Jest to z ciągami numerycznymi. Ale zgodnie z oczekiwaniami. Nawet w tym przypadku strona operatora jest włączona, nie ma znaczenia. http://www.ideone.com/UHD43 – profitphp

+0

Taa ... to dziwne, ale przynajmniej jest udokumentowane. Przyjęcie tej odpowiedzi jest ostateczne. – mpen

3

Krótko mówiąc, tak. $a == $b zawsze będzie odpowiednikiem $b == $a. Występują pewne niedociągnięcia, takie jak pływaki. Oczywiście, nie powinieneś i tak zagłębić się w równość.

EDIT
Odnośnie pływaków: Gdybyś miał dwa pływak i porównał je, one technicznie powinny być takie same. Jednak wartości zmiennoprzecinkowe, które wydają się mieć tę samą wartość, nie muszą być identyczne. Jeśli więc $a jest literałem .69 i $b jest wynikiem obliczeń, mogą one być bardzo różne, ale obie mają tę samą wartość. Dlatego nigdy nie powinieneś porównywać wartości zmiennoprzecinkowych, używając ==.

Jeśli chcesz porównać wartości zmiennoprzecinkowe, naprawdę musisz użyć najmniejszej akceptowalnej różnicy w konkretnym przypadku. Coś jak to będzie działać na porównywaniu pływaki (ustawienie naszą najmniejszą dopuszczalną różnicę w 0.000001):

if(abs($a-$b) < 0.000001) { 
    //Same 
} 

PHP: abs - Absolute Value

+2

Czy możesz podać przykład miejsca, w którym pływaki będą porównywać w jeden sposób, ale nie drugi? Rozumiem błędy zaokrąglania wynikające z pływów, ale czy nie powinny być konsekwentnie porównywane w żadnym kierunku? – mpen

+0

Zaktualizowałem moją odpowiedź, aby podać więcej informacji o porównaniach zmiennoprzecinkowych. Mam nadzieję, że to pomoże. –

+0

No it does not :) To trochę niezwiązane. W każdym razie dzięki. – mpen

2

http://php.net/manual/en/language.operators.comparison.php

Istnieje rozróżnianie operatorzy mogą użyć, jeśli rozważyć typu odlew w porównanie. == jest wartością równą true, ale nie porównuje typu danych. === jest wartością prawdy, gdy wartości są równe, a także typami danych. Użycie tego ostatniego rozważa typowanie, w którym normalnie byłoby ignorowane (np. Łańcuch reprezentujący liczbę całkowitą i liczbę całkowitą).

Kolejność logiki warunkowej nie powinna mieć znaczenia.

+2

Nie podoba mi się użycie słowa "powinien". Miałem nadzieję na ostateczną odpowiedź :) – mpen

1

Próbowałem wiele odmian i nie może znaleźć przypadek, gdy ($a == $b) !== ($b == $a) ale nikt do tej pory pracował:

<?php 

$a = 0; 
$b = "0"; 

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n"; 

$a = 0; 
$b = NULL; 

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n"; 

$a = 0; 
$b = false; 

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n"; 

$a = false; 
$b = NULL; 

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n"; 

$a = ""; 
$b = NULL; 

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n"; 

$a = "NULL"; 
$b = NULL; 

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n"; 

$a = 0.000000000000000000000000001; 
$b = 0; 

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n"; 

$a = array(); 
$b = array(); 

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n"; 

Tak, daję się w tym momencie. Pomysły mile widziane!

3

Jedynym rodzajem że mogłem zobaczyć inności jest coś takiego:

$foo = 1; 
$bar = 1; 

($foo = $foo + $bar) == ($bar = $foo); 

Aby zobaczyć dlaczego, spojrzeć na to

A -> ($foo = $foo + $bar) 
B -> ($bar = $foo); 

Jeśli A prowadzony jest pierwszy wynik będzie 2 i wynik B będzie wynosił 2, więc są one równe, a testem będzie true.

Jeśli B prowadzony jest pierwszy wynik będzie 1, a wynik B będzie 2, więc nie są one równe, a test będzie false.

Dla każdego pojedynczego porównania (gdzie A jest zmienną, a nie wyrażeniem), zawsze będzie refleksyjne.

W sensie ogólnym, A == B nie zawsze ma 100% gwarancji, że jest równoważne z B == A. W przypadku zmiennych zawsze będzie to odpowiednik. Ale w przypadku złożonych wyrażeń obejmujących przypisanie lub modyfikację zmiennych może nie być.

Powiązane problemy