2011-01-20 14 views
8

$a == $b her zaman $b == $a mu?Tüm PHP eşitliği karşılaştırmaları simetrik midir?

Javascript'te, döküm nedeniyle doğru olmayan birkaç garip vaka var.

ide'un doğru olduğunu düşünüyorum. Başka bir question soracağım.

+2

"Refleks" diyebilirim. – Joe

+0

@Joe: Teşekkürler. Güncellenmiş. – mpen

+1

@Joe doğrudur. Bu _reflexivity_ olarak kabul edilir. İlişkililik şu durumdadır: (A + B) + C = A + (B + C) ' – treeface

cevap

3

Bu iki çağrı arasında ne olduğuna bağlı. Aksi halde evet, bunlar aynı. Sipariş fark etmez. 2 eşittir == kullanma 1 ve 1 tamsayı bir dize karşılaştırıldığında karşılaştırılır. Tür göz ardı edilir, sadece değer karşılaştırılır. Yani gariplik yok.

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

<? 

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

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


echo $a==$b; 

Çıkışlar:

netleştirmek için 1

http://www.ideone.com/JLJWQ

DÜZENLEME, kesinlikle hiç $ a koyabilirsiniz hiçbir şey veya $ b almak için orada karşılaştırma üzerinde farklı bir çıktı, sadece operatörün diğer tarafına yerleştirerek.

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

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

herhangi $ a veya $ b değerleri için bu çıkış, her zaman şüphesiz doğrudur doğru mu, yoksa yanlış yanlış olacaktır.

+1

Evet, ama bu basit bir örnek. Belki de "01" gibi birtakım garip durumlar olduğunu düşündüm == 1 '1 bir dizgeye dönüştürülebildi ve sonra eşit olmazdı, ama 1 == "01" 'de dizge bir int ve sonra eşit olurlardı. Durumun böyle olmadığını biliyorum. http://www.php.net/manual/en/language.types.string.php#language.types.string.conversion Belki de bilmediğim bazı tuhaf şeyler var. – mpen

+0

iyi .. yorumlarda belirtilen bir tuhaf biri var. Sayısal dizeleri ile. Ama beklendiği gibi. Buna rağmen, operatörün her biri açık, önemli değil. http://www.ideone.com/UHD43 – profitphp

+0

Evet, bu garip ama en azından belgelendi. Bu cevabı kesin olarak kabul etmek. – mpen

3

Özetle, evet. $a == $b, her zaman $b == $a eşdeğeri olacaktır. Yüzen gibi bazı kısa gelenekler var. Elbette, yine de eşitlik için iki float yerleştirmemelisin.

DÜZENLEME
ilgili yüzer: İki float ve karşılaştırdı olsaydı, bunlar teknik olarak aynı olmalıdır. Bununla birlikte, aynı değere sahip gibi görünen kayan nokta değerlerinin aslında aynı olması gerekmez. Yani, $a bir literal .69 ve $b bir hesaplama sonucu, çok farklı olabilir, ancak her ikisi de aynı değeri görüntüler. Bu nedenle, == kullanarak kayan nokta değerlerini asla karşılaştırmamalısınız.

Kayan nokta değerlerini karşılaştırmanız gerekirse, özel durumunuzda kabul edilebilir en küçük farkı kullanmanız gerekir. Böyle bir şey yüzer karşılaştıran (0.000001 bizim en küçük kabul edilebilir bir fark ayarlama) için de kullanılabilir:

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

PHP: abs - Absolute Value

+2

Şamandıraların eşit bir şekilde karşılaştırılabileceği bir örnek verebilir misiniz, ama diğerini değil? Floatlar nedeniyle yuvarlama hatalarını anlıyorum, ancak her iki yönde tutarlı bir şekilde karşılaştırılmamalıdır? – mpen

+0

Cevabımı, float karşılaştırmaları hakkında daha fazla bilgi eklemek için güncelledim. Umut ediyorum bu yardım eder. –

+0

Hayır öyle değil :) Bu biraz ilgisiz. Yine de teşekkürler. – mpen

2

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

içeri türü çevrim dikkate almak isterseniz kullanabilirsiniz diffrent operatörler vardır mukayese. ==, eşit değerde doğru olarak değerlendirir, ancak veri türünü karşılaştırmaz. ===, değerler detatypes kadar eşit olduğunda doğru olarak değerlendirir. Sonuncusu kullanmak, normalde yok sayılacak tipte dökümü dikkate alır (örneğin: bir tamsayıyı temsil eden bir dize ve bir tamsayı karşılaştırılır.)

Koşultaki mantığın sırası, bir fark yaratmamalıdır.

+2

"should" kelimesini kullanmayı sevmiyorum. Kesin bir cevap umuyordum :) – mpen

1

Ben varyasyonları çok sayıda güvenilir ve şimdiye kadar çalışmış ($a == $b) !== ($b == $a) ama hiçbiri bir dava bulamıyor:

<?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"; 

Yani, bu noktada pes. Fikirler hoş geldiniz!

$foo = 1; 
$bar = 1; 

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

A ilk çalıştırıldığında bu

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

, sonuç 2 olacak ve bakmak, nedenini görmek için: Ben farklı olmak görebiliyordu

3

tek tip bir şey gibidir B sonucu 2 olacak, bu yüzden eşittir ve test true olacaktır. B ilk çalıştırılırsa

, sonuç 1 olacak ve B sonucu 2 olacak, bu yüzden eşit değildir ve test false olacaktır.

Ancak, herhangi bir tek tip karşılaştırması için (A bir değişken değil, bir ifadedir) her zaman yansıtıcı olacaktır. Bu nedenle, genel anlamda A == B, B == A'a eşdeğer% 100 garantili değildir. Değişkenler için her zaman eşdeğer olacaktır. Ancak, değişkenlerin atanmasını veya değiştirilmesini içeren karmaşık ifadeler için olmayabilir.