Odpowiedzi:
==
i===
Różnica między luźno ==
równym operatorem a ściśle ===
identycznym operatorem została dokładnie wyjaśniona w instrukcji :
Operatory porównania
┌──────────┬───────────┬────────────────────────── ─────────────────────────────────┐ │ Przykład │ Nazwa │ Wynik │ ├──────────┼───────────┼────────────────────────── ─────────────────────────────────┤ │ $ a == $ b │ Równe │ PRAWDA, jeśli $ a jest równe $ b po żonglowaniu typem. │ │ $ a === $ b │ Identyczne │ PRAWDA, jeśli $ a jest równe $ b i są tego samego typu. │ └──────────┴───────────┴────────────────────────── ─────────────────────────────────┘
==
równe porównanieJeśli używasz ==
operatora, lub dowolny inny operator porównania, które wykorzystuje luźno porównanie takie jak !=
, <>
lub ==
, zawsze trzeba spojrzeć na kontekst , aby zobaczyć, co, gdzie i dlaczego coś zostanie przekonwertowany do zrozumienia tego, co się dzieje.
Jako odniesienie i przykład możesz zobaczyć tabelę porównawczą w instrukcji :
Luźne porównania z
==
┌─────────┬───────┬───────┬───────┬───────┬─────── ┬───────┬───────┬───────┬───────┬─────────┬─────── ┬───────┐ │ │ PRAWDA │ FAŁSZ │ 1 │ 0 │ -1 │ „1” │ „0” │ „-1” │ NULL │ tablica () │ „php” │ „” │ ├─────────┼───────┼───────┼───────┼───────┼─────── ┼───────┼───────┼───────┼───────┼─────────┼─────── ┼───────┤ │ PRAWDA │ PRAWDA │ FAŁSZ │ PRAWDA │ FAŁSZ │ PRAWDA │ PRAWDA │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ PRAWDA │ PRAWDA │ FAŁSZ │ PRAWDA │ │ 1 │ PRAWDA │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ 0 │ FAŁSZ │ PRAWDA │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ PRAWDA │ FAŁSZ │ PRAWDA │ PRAWDA │ │ -1 │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ „1” │ PRAWDA │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ „0” │ FAŁSZ │ PRAWDA │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ „-1” │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ NULL │ FAŁSZ │ PRAWDA │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ PRAWDA │ FAŁSZ │ PRAWDA │ │ array () │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ TRUE │ FALSE │ FALSE │ Ph „php” │ PRAWDA │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ │ „” │ FAŁSZ │ PRAWDA │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ PRAWDA │ └─────────┴───────┴───────┴───────┴───────┴─────── ┴───────┴───────┴───────┴───────┴─────────┴─────── ┴───────┘
===
identyczne porównanieJeśli używasz ===
operatora lub dowolnego innego operatora porównania, który używa ścisłego porównania, takiego jak !==
lub ===
, zawsze możesz być pewien, że typy nie zmienią się magicznie , ponieważ nie nastąpi konwersja. Zatem przy ścisłym porównaniu typ i wartość muszą być takie same, a nie tylko wartość.
Jako odniesienie i przykład możesz zobaczyć tabelę porównawczą w instrukcji :
Ścisłe porównania z
===
┌─────────┬───────┬───────┬───────┬───────┬─────── ┬───────┬───────┬───────┬───────┬─────────┬─────── ┬───────┐ │ │ PRAWDA │ FAŁSZ │ 1 │ 0 │ -1 │ „1” │ „0” │ „-1” │ NULL │ tablica () │ „php” │ „” │ ├─────────┼───────┼───────┼───────┼───────┼─────── ┼───────┼───────┼───────┼───────┼─────────┼─────── ┼───────┤ │ PRAWDA │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ 1 │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ 0 │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ -1 │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ „1” │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ „0” │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ „-1” │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ NULL │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ FAŁSZ │ FAŁSZ │ │ array () │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ Ph „php” │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ FAŁSZ │ │ „” AL FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ FAŁSZ │ PRAWDA │ └─────────┴───────┴───────┴───────┴───────┴─────── ┴───────┴───────┴───────┴───────┴─────────┴─────── ┴───────┘
true
lub false
. Łatwo to rzucić. Jednak wszystkie inne wartości mają praktycznie nieograniczoną liczbę kombinacji. Jest "five" == 5
? array(0) == 0
? array(0,0,0) == 0
? 0.0000000000000000000000000000000000000000000000000001 == array()
?
false
różne tablice w javascript, ale true
dla PHP, o ile ich wartości są równe .
"000" != "00"
, "000" == null
, "000" == false
, "0x0" == false
, array() == 0
, false != null
, array() != null
, false == "0x0"
, false == "000"
. W PHP, to naprzeciwko zachowanie: "000" == "00"
, "000" != null
, "000" != false
, "0x0" != false
, array() != 0
, false == null
, array() == null
, false != "0x0"
, false != "000"
.
Operator == rzuca między dwoma różnymi typami, jeśli są one różne, podczas gdy operator === wykonuje „porównanie typów”. Oznacza to, że zwróci prawdę tylko wtedy, gdy oba operandy mają ten sam typ i tę samą wartość.
Przykłady:
1 === 1: true
1 == 1: true
1 === "1": false // 1 is an integer, "1" is a string
1 == "1": true // "1" gets casted to an integer, which is 1
"foo" === "foo": true // both operands are strings and have the same value
Ostrzeżenie : dwa wystąpienia tej samej klasy z równoważnymi elementami NIE są zgodne z ===
operatorem. Przykład:
$a = new stdClass();
$a->foo = "bar";
$b = clone $a;
var_dump($a === $b); // bool(false)
Obraz jest wart tysiąca słów:
==
Tabela równości PHP Double Equals :===
Equality wykres:Kod źródłowy, aby utworzyć te obrazy:
https://github.com/sentientmachine/php_equality_charts
Ci, którzy chcą zachować zdrowie psychiczne, nie czytają dalej, ponieważ nic z tego nie będzie miało sensu, z wyjątkiem twierdzenia, że tak zaprojektowano fraktal szaleństwa PHP.
NAN != NAN
ale NAN == true
. ==
konwertuje lewy i prawy operand na liczby, jeśli lewy jest liczbą. No 123 == "123foo"
ale"123" != "123foo"
Ciąg szesnastkowy w cudzysłowie jest czasem zmiennoprzecinkowy i będzie niespodziewanie rzucany, aby unosić się wbrew twojej woli, powodując błąd w czasie wykonywania.
==
nie jest przechodnie, ponieważ "0"== 0
i 0 == ""
ale"0" != ""
==
."6" == " 6"
, "4.2" == "4.20"
i "133" == "0133"
ale 133 != 0133
. Ale "0x10" == "16"
i "1e3" == "1000"
wystawienie takiej konwersji niespodzianka ciąg do ósemkowej wystąpią zarówno bez instrukcji lub zgody, powodując błąd wykonania.
False == 0
, ""
, []
I "0"
.
Gdy liczby są wystarczająco duże, to == nieskończoność.
Świeża klasa to == do 1.
Jeśli używasz PHP, nie powinieneś używać operatora podwójnej równości, ponieważ jeśli używasz potrójnej równości, jedynymi przypadkami, o które należy się martwić, są NAN i liczby tak bliskie nieskończoności, że są rzutowane na nieskończoność. W przypadku podwójnych równości wszystko może być niespodzianką ==
dla każdego lub może być niespodzianką rzuconą wbrew twojej woli i !=
na coś, co oczywiście powinno być równe.
W każdym miejscu, w którym używasz ==
PHP, jest nieprzyjemny zapach kodu z powodu 85 błędów w nim ujawnionych przez niejawne reguły rzutowania, które wydają się projektowane przez miliony programistów programujących ruchem Brownian.
W odniesieniu do JavaScript:
Operator === działa tak samo jak operator ==, ale wymaga, aby jego operandy miały nie tylko tę samą wartość, ale także ten sam typ danych.
Na przykład poniższa próbka wyświetli „xiy są równe”, ale nie „xiy są identyczne”.
var x = 4;
var y = '4';
if (x == y) {
alert('x and y are equal');
}
if (x === y) {
alert('x and y are identical');
}
Dodatek do innych odpowiedzi dotyczących porównania obiektów:
== porównuje obiekty na podstawie nazwy obiektu i ich wartości. Jeśli dwa obiekty są tego samego typu i mają te same wartości $a == $b
składowe , zwraca true.
=== porównuje wewnętrzny identyfikator obiektu dla obiektów. Nawet jeśli członkowie są równi, $a !== $b
jeśli nie są dokładnie tym samym przedmiotem.
class TestClassA {
public $a;
}
class TestClassB {
public $a;
}
$a1 = new TestClassA();
$a2 = new TestClassA();
$b = new TestClassB();
$a1->a = 10;
$a2->a = 10;
$b->a = 10;
$a1 == $a1;
$a1 == $a2; // Same members
$a1 != $b; // Different classes
$a1 === $a1;
$a1 !== $a2; // Not the same object
Mówiąc najprościej:
== sprawdza, czy ekwiwalent (tylko wartość)
=== sprawdza, czy ten sam (wartość i typ)
Odpowiednik kontra taki sam: analogia
1 + 1 = 2 + 0 (odpowiednik)
1 + 1 = 1 + 1 (to samo)
W PHP:
true == 1 (true - wartość równoważna)
true === 1 (false - nie taki sam pod względem wartości i typu)
Chodzi o typy danych. Weźmy na przykład BOOL
(prawda lub fałsz):
true
również równa się, 1
a
false
także równa się0
==
Nie dba o typach danych przy porównywaniu: Więc jeśli miał zmienną, która jest 1 (co może być również true
):
$var=1;
A następnie porównaj z ==
:
if ($var == true)
{
echo"var is true";
}
Ale $var
tak naprawdę nie jest równy true
, prawda? 1
Zamiast tego ma wartość int , która z kolei jest równa true.
Za ===
pomocą typy danych są sprawdzane, aby upewnić się, że dwie zmienne / obiekty / cokolwiek używają tego samego typu.
Więc gdybym to zrobił
if ($var === true)
{
echo "var is true";
}
warunek ten nie byłby spełniony, ponieważ $var !== true
jest == true
( tylko jeśli wiesz, co mam na myśli).
Dlaczego miałbyś tego potrzebować?
Proste - spójrzmy na jedną z funkcji PHP array_search()
:
array_search()
Funkcja po prostu wyszukuje wartość w tablicy i zwraca kluczowego elementu wartość została znaleziona. Jeśli wartość nie została znaleziona w tablicy, zwraca false . Ale co jeśli zrobiłeś array_search()
na wartości zapisanej w pierwszym elemencie tablicy (który miałby klucz tablicy 0
) ... array_search()
funkcja zwróciłaby 0 ... co jest równe false ...
Więc jeśli zrobiłeś:
$arr = array("name");
if (array_search("name", $arr) == false)
{
// This would return 0 (the key of the element the val was found
// in), but because we're using ==, we'll think the function
// actually returned false...when it didn't.
}
Czy widzisz, jak może to być teraz problem?
Większość ludzi nie używa == false
, sprawdzając, czy funkcja zwraca false. Zamiast tego używają !
. Ale w rzeczywistości jest to dokładnie to samo, co używanie ==false
, więc jeśli zrobiłeś:
$arr = array("name");
if (!array_search("name", $arr)) // This is the same as doing (array_search("name", $arr) == false)
W przypadku takich rzeczy należy użyć ===
zamiast tego, aby sprawdzić typ danych.
Jednym z przykładów jest to, że atrybut bazy danych może mieć wartość NULL lub „”:
$attributeFromArray = "";
if ($attributeFromArray == ""){} //true
if ($attributeFromArray === ""){} //true
if ($attributeFromArray == null){} //true
if ($attributeFromArray === null){} //false
$attributeFromArray = null;
if ($attributeFromArray == ""){} //true
if ($attributeFromArray === ""){} //false
if ($attributeFromArray == null){} //true
if ($attributeFromArray === null){} //true
php == to operator porównania, który porównuje wartość zmiennych. Ale === porównuje wartość i typ danych.
Na przykład,
<?php
$var1 = 10;
$var2 = '10';
if($var1 == $var2) {
echo 'Variables are equal';
} else {
echo 'Variables are not equal';
}
?>
W takim przypadku wynikiem będą „Zmienne są równe”, nawet jeśli ich typy danych są różne.
Ale jeśli użyjemy === zamiast ==, wynikiem będzie „Zmienne nie są równe”. PHP najpierw porównuje wartość zmiennej, a następnie typ danych. Tutaj wartości są takie same, ale typy danych są różne.
Dany x = 5
1) Operator: == jest „równy”. x == 8
jest fałszem
2) Operator: === jest „dokładnie równy” (wartość i typ) x === 5
jest prawdą, x === "5"
jest fałszem
$a = 5; // 5 as an integer
var_dump($a == 5); // compare value; return true
var_dump($a == '5'); // compare value (ignore type); return true
var_dump($a === 5); // compare type/value (integer vs. integer); return true
var_dump($a === '5'); // compare type/value (integer vs. string); return false
Bądź jednak ostrożny. Oto znany problem.
// 'test' is found at position 0, which is interpreted as the boolean 'false'
if (strpos('testing', 'test')) {
// code...
}
vs.
// true, as strict comparison was made (0 !== false)
if (strpos('testing', 'test') !== false) {
// code...
}
Krótko mówiąc, === działa w taki sam sposób, jak == w większości innych języków programowania.
PHP pozwala na dokonywanie porównań, które tak naprawdę nie mają sensu. Przykład:
$y = "wauv";
$x = false;
if ($x == $y)
...
Chociaż pozwala to na kilka interesujących „skrótów”, powinieneś się wystrzegać, ponieważ funkcja, która zwraca coś, czego nie powinna (np. „Błąd” zamiast liczby), nie zostanie złapana i będziesz zastanawiać się, co się stało.
W PHP == porównuje wartości iw razie potrzeby dokonuje konwersji typu (na przykład ciąg „12343sdfjskfjds” zmieni się na „12343” w porównaniu liczb całkowitych). === porówna wartość ORAZ typ i zwróci false, jeśli typ nie jest taki sam.
Jeśli zajrzysz do instrukcji PHP, zobaczysz, że wiele funkcji zwraca „fałsz”, jeśli funkcja się nie powiedzie, ale mogą zwrócić 0 w udanym scenariuszu, dlatego zalecają wykonanie „if (function ()! == false) ”, aby uniknąć błędów.
Kilka przykładów
var_dump(5 == 5); // True
var_dump(5 == "5"); // True because == checks only same value not type
var_dump(5 === 5); // True
var_dump(5 === "5"); // False because value are same but data type are different.
PS
== Porównuje tylko wartość, nie przejmuje się typami danych
vs.
=== Porównuje wartości i typy danych
Użyłbyś ===, aby sprawdzić, czy funkcja lub zmienna jest fałszem, a nie tylko zrównaniem się z fałszem (zero lub pusty ciąg znaków).
$needle = 'a';
$haystack = 'abc';
$pos = strpos($haystack, $needle);
if ($pos === false) {
echo $needle . ' was not found in ' . $haystack;
} else {
echo $needle . ' was found in ' . $haystack . ' at location ' . $pos;
}
W tym przypadku strpos zwróci 0, co w teście będzie równe false
if ($pos == false)
lub
if (!$pos)
co nie jest tym, czego chcesz tutaj.
Jeśli chodzi o to, kiedy używać jednego nad drugim, weźmy na przykład fwrite()
funkcję w PHP.
Ta funkcja zapisuje zawartość w strumieniu plików. Według PHP „ fwrite()
zwraca liczbę zapisanych bajtów lub FAŁSZ w przypadku błędu.”. Jeśli chcesz sprawdzić, czy wywołanie funkcji zakończyło się powodzeniem, ta metoda jest wadliwa:
if (!fwrite(stuff))
{
log('error!');
}
Może zwrócić zero (i jest uważane za udane), a twój stan nadal jest wyzwalany. Właściwy sposób to:
if (fwrite(stuff) === FALSE)
{
log('error!');
}
PHP to luźno napisany język. Użycie operatora podwójnej równości pozwala na swobodne sprawdzanie zmiennej.
Luźne sprawdzenie wartości pozwoliłoby na zrównanie niektórych podobnych, ale nie równych wartości:
Wszystkie te wartości byłyby równe za pomocą operatora podwójnej równości.
Zmienne mają typ i wartość.
Kiedy używasz tych zmiennych (w PHP), czasami nie masz dobrego typu. Na przykład jeśli tak
if ($var == 1) {... do something ...}
PHP musi przekonwertować („rzutować”) $ var na liczbę całkowitą. W tym przypadku „$ var == 1” jest prawdziwe, ponieważ każdy niepusty ciąg jest rzutowany na 1.
Używając ===, sprawdzasz, czy wartość I TYP są równe, więc "$ var === 1" jest fałszem.
Jest to przydatne na przykład, gdy masz funkcję, która może zwrócić false (w przypadku błędu) i 0 (wynik):
if(myFunction() == false) { ... error on myFunction ... }
Ten kod jest niepoprawny, jakby myFunction()
zwracał 0, jest rzutowany na false i wydaje się, że masz błąd. Prawidłowy kod to:
if(myFunction() === false) { ... error on myFunction ... }
ponieważ test polega na tym, że zwracana wartość „jest wartością logiczną i jest fałszem”, a nie „może być rzutowana na fałsz”.
===
Operator ma porównać dokładnie równości treści natomiast ==
operator będzie porównać semantycznej równości. W szczególności zmusi ciągi do liczb.
Równość jest obszernym przedmiotem. Zobacz artykuł w Wikipedii na temat równości .
<?php
/**
* Comparison of two PHP objects == ===
* Checks for
* 1. References yes yes
* 2. Instances with matching attributes and its values yes no
* 3. Instances with different attributes yes no
**/
// There is no need to worry about comparing visibility of property or
// method, because it will be the same whenever an object instance is
// created, however visibility of an object can be modified during run
// time using ReflectionClass()
// http://php.net/manual/en/reflectionproperty.setaccessible.php
//
class Foo
{
public $foobar = 1;
public function createNewProperty($name, $value)
{
$this->{$name} = $value;
}
}
class Bar
{
}
// 1. Object handles or references
// Is an object a reference to itself or a clone or totally a different object?
//
// == true Name of two objects are same, for example, Foo() and Foo()
// == false Name of two objects are different, for example, Foo() and Bar()
// === true ID of two objects are same, for example, 1 and 1
// === false ID of two objects are different, for example, 1 and 2
echo "1. Object handles or references (both == and ===) <br />";
$bar = new Foo(); // New object Foo() created
$bar2 = new Foo(); // New object Foo() created
$baz = clone $bar; // Object Foo() cloned
$qux = $bar; // Object Foo() referenced
$norf = new Bar(); // New object Bar() created
echo "bar";
var_dump($bar);
echo "baz";
var_dump($baz);
echo "qux";
var_dump($qux);
echo "bar2";
var_dump($bar2);
echo "norf";
var_dump($norf);
// Clone: == true and === false
echo '$bar == $bar2';
var_dump($bar == $bar2); // true
echo '$bar === $bar2';
var_dump($bar === $bar2); // false
echo '$bar == $baz';
var_dump($bar == $baz); // true
echo '$bar === $baz';
var_dump($bar === $baz); // false
// Object reference: == true and === true
echo '$bar == $qux';
var_dump($bar == $qux); // true
echo '$bar === $qux';
var_dump($bar === $qux); // true
// Two different objects: == false and === false
echo '$bar == $norf';
var_dump($bar == $norf); // false
echo '$bar === $norf';
var_dump($bar === $norf); // false
// 2. Instances with matching attributes and its values (only ==).
// What happens when objects (even in cloned object) have same
// attributes but varying values?
// $foobar value is different
echo "2. Instances with matching attributes and its values (only ==) <br />";
$baz->foobar = 2;
echo '$foobar' . " value is different <br />";
echo '$bar->foobar = ' . $bar->foobar . "<br />";
echo '$baz->foobar = ' . $baz->foobar . "<br />";
echo '$bar == $baz';
var_dump($bar == $baz); // false
// $foobar's value is the same again
$baz->foobar = 1;
echo '$foobar' . " value is the same again <br />";
echo '$bar->foobar is ' . $bar->foobar . "<br />";
echo '$baz->foobar is ' . $baz->foobar . "<br />";
echo '$bar == $baz';
var_dump($bar == $baz); // true
// Changing values of properties in $qux object will change the property
// value of $bar and evaluates true always, because $qux = &$bar.
$qux->foobar = 2;
echo '$foobar value of both $qux and $bar is 2, because $qux = &$bar' . "<br />";
echo '$qux->foobar is ' . $qux->foobar . "<br />";
echo '$bar->foobar is ' . $bar->foobar . "<br />";
echo '$bar == $qux';
var_dump($bar == $qux); // true
// 3. Instances with different attributes (only ==)
// What happens when objects have different attributes even though
// one of the attributes has same value?
echo "3. Instances with different attributes (only ==) <br />";
// Dynamically create a property with the name in $name and value
// in $value for baz object
$name = 'newproperty';
$value = null;
$baz->createNewProperty($name, $value);
echo '$baz->newproperty is ' . $baz->{$name};
var_dump($baz);
$baz->foobar = 2;
echo '$foobar' . " value is same again <br />";
echo '$bar->foobar is ' . $bar->foobar . "<br />";
echo '$baz->foobar is ' . $baz->foobar . "<br />";
echo '$bar == $baz';
var_dump($bar == $baz); // false
var_dump($bar);
var_dump($baz);
?>
Wszystkie dotychczasowe odpowiedzi ignorują niebezpieczny problem z ===. Na marginesie zauważono, ale nie podkreślono, że liczby całkowite i podwójne są różnymi typami, więc następujący kod:
$n = 1000;
$d = $n + 0.0e0;
echo '<br/>'. ( ($n == $d)?'equal' :'not equal' );
echo '<br/>'. ( ($n === $d)?'equal' :'not equal' );
daje:
equal
not equal
Zauważ, że NIE jest to przypadek „błędu zaokrąglania”. Dwie liczby są dokładnie równe do ostatniego bitu, ale mają różne typy.
Jest to paskudny problem, ponieważ program używający === może z powodzeniem działać przez lata, jeśli wszystkie liczby są wystarczająco małe (gdzie „wystarczająco małe” zależy od sprzętu i systemu operacyjnego, na którym pracujesz). Jeśli jednak przypadkiem liczba całkowita będzie wystarczająco duża, aby przekształcić ją w podwójną, jej typ zostanie zmieniony „na zawsze”, nawet jeśli kolejna operacja lub wiele operacji może przywrócić jej wartość do małej liczby całkowitej. I jest coraz gorzej. Może się rozprzestrzeniać - infekcja podwójności może być przenoszona na wszystko, czego dotknie, jedno obliczenie na raz.
W prawdziwym świecie może to stanowić problem na przykład w programach obsługujących daty po roku 2038. W tej chwili znaczniki czasu UNIX (liczba sekund od 1970-01-01 00:00:00 UTC) będą wymagały więcej niż 32-bitów, więc ich reprezentacja „magicznie” przełączy się na podwojona w niektórych systemach. Dlatego jeśli obliczysz różnicę dwa razy, możesz skończyć z kilkoma sekundami, ale jako podwójną, a nie liczbą całkowitą, która występuje w 2017 roku.
Myślę, że jest to znacznie gorsze niż konwersje między ciągami i liczbami, ponieważ jest subtelne. Śledzenie tego, co jest ciągiem, a co liczbą, jest dla mnie łatwe, ale śledzenie liczby bitów w liczbie jest poza mną.
Tak więc, w powyższych odpowiedziach jest kilka fajnych tabel, ale nie ma rozróżnienia między 1 (jako liczba całkowita) i 1 (subtelne podwójne) i 1.0 (oczywiste podwójne). Również rada, której powinieneś zawsze używać === i nigdy ==, nie jest świetna, ponieważ === czasami zawiedzie, gdy == działa poprawnie. Również JavaScript nie jest pod tym względem równoważny, ponieważ ma tylko jeden typ liczb (wewnętrznie może mieć różne reprezentacje bitowe, ale nie powoduje problemów dla ===).
Moja rada - nie używaj żadnej. Musisz napisać własną funkcję porównania, aby naprawdę naprawić ten bałagan.
Istnieją dwie różnice między nimi ==
i===
w tablic i obiektów, które moim zdaniem nie wspomnieć tutaj PHP; dwie tablice z różnymi rodzajami kluczy i obiektami.
Jeśli masz tablicę z sortowaniem według klucza i inną tablicę z innym sortowaniem według klucza, są one całkowicie różne (tzn. Używają ===
). Może to spowodować, jeśli posortujesz tablicę kluczem i spróbujesz porównać posortowaną tablicę z oryginalną.
Rozważmy na przykład pustą tablicę. Najpierw próbujemy wypchnąć kilka nowych indeksów do tablicy bez żadnego specjalnego rodzaju. Dobrym przykładem może być tablica z ciągami znaków jako kluczami. Teraz głęboko w przykład:
// Define an array
$arr = [];
// Adding unsorted keys
$arr["I"] = "we";
$arr["you"] = "you";
$arr["he"] = "they";
Teraz mamy tablicę nieposortowanych kluczy (np. „On” pojawił się po „tobie”). Rozważ tę samą tablicę, ale posortowaliśmy jej klucze alfabetycznie:
// Declare array
$alphabetArr = [];
// Adding alphabetical-sorted keys
$alphabetArr["I"] = "we";
$alphabetArr["he"] = "they";
$alphabetArr["you"] = "you";
Wskazówka : możesz sortować tablicę według klucza za pomocą ksort () .
Teraz masz inną tablicę z innym rodzajem klucza niż pierwszy. Porównamy je:
$arr == $alphabetArr; // true
$arr === $alphabetArr; // false
Uwaga : Może to być oczywiste, ale zawsze porównanie dwóch różnych tablic przy użyciu ścisłego porównania false
. Jednak dwie dowolne tablice mogą być równe przy użyciu ===
lub nie.
Powiedziałbyś: „Ta różnica jest znikoma”. Mówię wtedy, że to różnica, którą należy rozważyć i może się zdarzyć w dowolnym momencie. Jak wspomniano powyżej, sortowanie kluczy w tablicy jest tego dobrym przykładem.
Pamiętaj, że dwa różne obiekty nigdy nie są sobie równe . Te przykłady pomogłyby:
$stdClass1 = new stdClass();
$stdClass2 = new stdClass();
$clonedStdClass1 = clone $stdClass1;
// Comparing
$stdClass1 == $stdClass2; // true
$stdClass1 === $stdClass2; // false
$stdClass1 == $clonedStdClass1; // true
$stdClass1 === $clonedStdClass1; // false
Uwaga : Przypisanie obiektu do innej zmiennej nie tworzy kopii - tworzy raczej odwołanie do tej samej lokalizacji pamięci co obiekt. Spójrz tutaj .
Uwaga : Od PHP7 dodano anonimowe klasy . Z wyników, nie ma różnicy między new class {}
i new stdClass()
w testach powyżej.