Apa perbedaan antara operator PHP equality (== double equals) dan identitas (=== triple equals)?

509

Apa perbedaan antara ==dan ===?

  • Bagaimana tepatnya cara ==kerja perbandingan longgar ?
  • Bagaimana tepatnya cara ===kerja perbandingan ketat ?

Apa yang akan menjadi contoh yang bermanfaat?

nickf
sumber

Jawaban:

633

Perbedaan antara ==dan===

Perbedaan antara ==operator yang secara longgar sama dan operator yang ===identik persis dijelaskan dalam manual :

Operator Perbandingan

┌─────────┬──────────────────────────────────── ───────────────────────────────
│ Contoh │ Nama │ Hasil │
├─────────┼──────────────────────────────────── ───────────────────────────────
│ $ a == $ b │ Sama │ BENAR jika $ a sama dengan $ b setelah jenis juggling. │
│ $ a === $ b │ Identik │ BENAR jika $ a sama dengan $ b, dan mereka memiliki tipe yang sama. │
└─────────┴──────────────────────────────────── ───────────────────────────────

Longgar ==perbandingan yang sama

Jika Anda menggunakan ==operator, atau operator perbandingan lainnya yang menggunakan perbandingan longgar seperti !=, <>atau ==, Anda selalu harus melihat konteksnya untuk melihat apa, di mana dan mengapa sesuatu dikonversi untuk memahami apa yang sedang terjadi.

Aturan konversi

Ketikkan tabel perbandingan

Sebagai referensi dan contoh Anda dapat melihat tabel perbandingan dalam manual :

Perbandingan longgar dengan ==

┌───────────────────────┬───────────────────── ┬──────────────┬─────────────────────────────── ┬───────┐
│ │ BENAR │ SALAH │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array () │ "php" │ "" │
├───────────────────────┼───────────────────── ┼──────────────┼─────────────────────────────── ┼───────┤
│ BENAR │ BENAR │ SALAH │ BENAR │ SALAH │ BENAR │ BENAR │ BENAR │ BENAR │ BENAR AL BENAR │ BENAR │ BENAR │
│ SALAH │ SALAH │ BENAR │ SALAH │ BENAR │ SALAH │ SALAH │ BENAR │ BENAR │ BENAR │ BENAR │ BENAR │ BENAR │ BENAR │
│ 1 │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ BENAR │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ 0 │ FALSE │ BENAR │ FALSE │ BENAR │ FALSE │ FALSE │ BENAR │ BENAR │ BENAR │ BENAR │ BENAR │ BENAR │ BENAR │
│ -1 │ BENAR │ FALSE │ FALSE │ FALSE │ BENAR │ FALSE │ FALSE │ BENAR │ FALSE │ FALSE │ FALSE │ FALSE │
│ "1" │ BENAR │ FALSE │ BENAR │ FALSE │ FALSE │ BENAR │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ "0" │ FALSE │ BENAR │ FALSE │ BENAR │ FALSE │ FALSE │ BENAR │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ "-1" │ BENAR │ FALSE │ FALSE │ FALSE │ BENAR │ FALSE │ BENAR │ BENAR │ FALSE │ FALSE │ FALSE │ FALSE │
│ NULL │ FALSE │ BENAR │ FALSE │ BENAR │ FALSE │ FALSE │ FALSE │ BENAR │ BENAR │ BENAR │ BENAR │ BENAR │ BENAR │
│ array () │ FALSE │ BENAR │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ BENAR │ BENAR │ BENAR │ FALSE │ FALSE │
│ "php" │ BENAR │ FALSE │ FALSE │ BENAR │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ BENAR │ BENAR │ FALSE │
│ "" │ FALSE │ BENAR │ FALSE │ BENAR │ FALSE │ FALSE │ FALSE │ BENAR │ BENAR │ FALSE │ FALSE │ BENAR │ BENAR │
└───────────────────────┴───────────────────── ┴──────────────┴─────────────────────────────── ┴───────┘

===Perbandingan identik yang ketat

Jika Anda menggunakan ===operator, atau operator perbandingan lainnya yang menggunakan perbandingan ketat seperti !==atau ===, maka Anda selalu dapat memastikan bahwa jenisnya tidak akan berubah secara ajaib , karena tidak akan ada konversi yang terjadi. Jadi dengan perbandingan ketat, jenis dan nilai harus sama, bukan hanya nilainya.

Ketikkan tabel perbandingan

Sebagai referensi dan contoh Anda dapat melihat tabel perbandingan dalam manual :

Perbandingan ketat dengan ===

┌───────────────────────┬───────────────────── ┬──────────────┬─────────────────────────────── ┬───────┐
│ │ BENAR │ SALAH │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array () │ "php" │ "" │
├───────────────────────┼───────────────────── ┼──────────────┼─────────────────────────────── ┼───────┤
│ BENAR │ BENAR │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ 1 │ FALSE │ FALSE │ BENAR AL FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ 0 │ FALSE │ FALSE │ FALSE │ BENAR │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ -1 │ FALSE │ FALSE │ FALSE │ FALSE │ BENAR │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ "1" │ FALSE │ FALSE AL FALSE │ FALSE │ FALSE UE BENAR │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ "0" │ FALSE │ FALSE AL FALSE │ FALSE │ FALSE │ BENAR │ BENAR │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ "-1" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ BENAR │ BENAR │ FALSE │ FALSE │ FALSE │ FALSE │
│ NULL │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ BENAR │ BENAR │ FALSE │ FALSE │ FALSE │
│ array () │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ BENAR │ BENAR │ FALSE │ FALSE │
│ "php" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ TRUE │ FALSE │
│ "" │ FALSE │ FALSE AL FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ BENAR │
└───────────────────────┴───────────────────── ┴──────────────┴─────────────────────────────── ┴───────┘
nickf
sumber
66
apakah ada orang lain yang merasa aneh bahwa "000" == "0000"?
nickf
36
Yang selalu mengejutkan saya adalah false == array (), dan false == 0 tetapi array ()! = 0, jadi false == array ()! = / == 0? itu terasa aneh bagiku.
Pim Jager
4
@Pim ... melanjutkan: Lihat seperti ini: Casting ke BOOL, nilai apa pun hanya jatuh di salah satu dari dua sisi, trueatau false. Itu mudah dilemparkan. Semua nilai lain memiliki, untuk semua tujuan praktis, kombinasi hampir tak terbatas. Benarkah "five" == 5? array(0) == 0? array(0,0,0) == 0? 0.0000000000000000000000000000000000000000000000000001 == array()?
deceze
12
@ Raithlin, hati-hati array. triple equals memberi falseuntuk array yang berbeda dalam javascript, tetapi trueuntuk PHP selama nilainya sama .
Pacerier
14
@ Raithlin, Masih banyak lagi Gotcha. Dalam JavaScript: "000" != "00" , "000" == null, "000" == false, "0x0" == false, array() == 0, false != null, array() != null, false == "0x0", false == "000". Dalam PHP, itu perilaku yang berlawanan: "000" == "00" , "000" != null, "000" != false, "0x0" != false, array() != 0, false == null, array() == null, false != "0x0", false != "000".
Pacerier
239

Operator == melakukan cast di antara dua tipe yang berbeda jika berbeda, sedangkan operator === melakukan 'perbandingan yang aman'. Itu berarti bahwa itu hanya akan mengembalikan true jika kedua operan memiliki tipe dan nilai yang sama.

Contoh:

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

Peringatan : dua instance dari kelas yang sama dengan anggota yang setara TIDAK cocok dengan ===operator. Contoh:

$a = new stdClass();
$a->foo = "bar";
$b = clone $a;
var_dump($a === $b); // bool(false)
Patrick Glandien
sumber
3
Nitpick: === hanya akan mengembalikan true jika kedua operan adalah tipe yang sama dan nilai-nilai yang sama =)
gnud
1
@gnud Itulah yang dia tunjukkan dalam contoh. Jika itu hanya membandingkan jenis itu hanya akan disebut "perbandingan jenis" bukan.
Rob Stevenson-Leggett
3
Setelah menggunakan PHP selama 8 tahun, kemarin adalah pertama kalinya saya terjebak dalam situasi di mana saya seharusnya menggunakan ===
3
=== Benar jika mereka sama dan memiliki tipe yang sama. == true jika keduanya sama. ! = true jika keduanya tidak sama. ! == true jika keduanya tidak sama, atau sama tetapi bukan tipe yang sama.
Jeremy C
1
Juga, menggunakan === sedikit lebih cepat daripada == karena tidak perlu mengkonversi nilai sebelum memeriksa apakah itu sama.
clauziere
88

Sebuah gambar bernilai ribuan kata:

==Bagan persamaan kesetaraan PHP Double Equals :

masukkan deskripsi gambar di sini

PHP Triple Equals ===Equality chart:

masukkan deskripsi gambar di sini

Kode sumber untuk membuat gambar-gambar ini:

https://github.com/sentientmachine/php_equality_charts

Meditasi Guru

Mereka yang ingin menjaga kewarasannya, tidak membaca lebih lanjut karena semua ini tidak masuk akal, kecuali untuk mengatakan bahwa ini adalah bagaimana kegilaan-fraktal, dari PHP dirancang.

  1. NAN != NANtapi NAN == true.
  2. ==akan mengkonversi operan kiri dan kanan ke angka jika kiri adalah angka. Jadi 123 == "123foo", tapi"123" != "123foo"
  3. String heksa dalam tanda kutip kadang-kadang merupakan float, dan akan diberikan kejutan untuk mengapung melawan kehendak Anda, menyebabkan kesalahan runtime.

  4. ==tidak transitif karena "0"== 0, dan 0 == ""tetapi"0" != ""

  5. Variabel PHP yang belum dideklarasikan adalah salah, meskipun PHP memiliki cara untuk mewakili variabel yang tidak ditentukan, fitur tersebut dinonaktifkan ==.
  6. "6" == " 6",, "4.2" == "4.20"dan "133" == "0133"tapi 133 != 0133. Tetapi "0x10" == "16"dan "1e3" == "1000"mengekspos konversi string kejutan menjadi oktal akan terjadi baik tanpa instruksi atau persetujuan Anda, menyebabkan kesalahan runtime.

  7. False == 0, "", []Dan "0".

  8. Ketika angka cukup besar mereka == Infinity.

  9. Kelas baru adalah == hingga 1.

  10. False adalah nilai yang paling berbahaya karena False adalah == untuk sebagian besar variabel lain, sebagian besar mengalahkan tujuannya.

Berharap:

Jika Anda menggunakan PHP, Anda tidak boleh menggunakan operator sama dengan ganda karena jika Anda menggunakan triple sama dengan, satu-satunya kasus tepi yang perlu dikhawatirkan adalah NAN dan angka yang begitu dekat hingga tak terbatas sehingga mereka dilemparkan ke tak terhingga. Dengan double equals, apa pun bisa mengejutkan ==apa pun atau, atau kejutan yang dilemparkan melawan kehendak Anda dan !=untuk sesuatu yang jelas harus sama.

Di mana pun Anda menggunakan ==PHP adalah bau kode yang buruk karena 85 bug di dalamnya diekspos oleh aturan casting implisit yang tampaknya dirancang oleh jutaan pemrogram pemrograman oleh gerakan brown.

Eric Leschinski
sumber
Apakah benar-benar ide yang bagus (juga aman) untuk selalu menggunakan triple sama dengan?
Chazy Chaz
3
Ya, properti transitif tiga sama dengan membuatnya lebih aman dan berskala web.
Eric Leschinski
Bagaimana suatu angka bisa mendekati tak terhingga? [meledak otak gif]
Tim
40

Berkenaan dengan JavaScript:

Operator === bekerja sama dengan operator ==, tetapi mengharuskan operan tidak hanya memiliki nilai yang sama, tetapi juga tipe data yang sama.

Misalnya, sampel di bawah ini akan menampilkan 'x dan y sama', tetapi bukan 'x dan y identik'.

var x = 4;
var y = '4';
if (x == y) {
    alert('x and y are equal');
}
if (x === y) {
    alert('x and y are identical');
}
Peter Mortensen
sumber
Terpilih, karena ini tampaknya situasi yang persis sama untuk php.
David mengatakan mengembalikan Monica
1
@ Davidvidomas Ini tidak persis sama. Lihat stackoverflow.com/questions/12598407/…
xdazz
22

Tambahan untuk jawaban lain tentang perbandingan objek:

== membandingkan objek menggunakan nama objek dan nilainya. Jika dua objek memiliki tipe yang sama dan memiliki nilai anggota yang sama, $a == $bmenghasilkan true.

=== membandingkan id objek internal objek. Sekalipun anggotanya setara, $a !== $bjika mereka bukan objek yang sama persis.

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
soulmerge
sumber
12

Secara sederhana:

== memeriksa apakah setara (hanya nilai)

=== memeriksa apakah sama (nilai && jenis)


Setara vs Sama: An Analogi

1 + 1 = 2 + 0 (setara)

1 + 1 = 1 + 1 (sama) di


PHP:

true == 1 (true - bernilai setara)

true === 1 (false - tidak sama dengan nilai && jenis)

  • benar adalah boolean
  • 1 adalah int
perak
sumber
"=== memeriksa jika sama (nilai && jenis)", tidak sepenuhnya benar. Dua objek stdClass memiliki tipe 'objek' yang sama (yaitu menggunakan gettype ()), tetapi PHP mengatakan mereka dua hal yang berbeda jika Anda menggunakan perbandingan yang ketat. Lihat ini .
MAChitgarha
8

Ini semua tentang tipe data. Ambil BOOL(benar atau salah) misalnya:

truejuga sama 1dan falsejuga sama0

Tidak ==peduli tentang tipe data saat membandingkan: Jadi jika Anda memiliki variabel yaitu 1 (yang juga bisa jadi true):

$var=1;

Dan kemudian bandingkan dengan ==:

if ($var == true)
{
    echo"var is true";
}

Tapi $varsebenarnya tidak sama true, kan? Ini memiliki nilai int 1sebagai gantinya, yang pada gilirannya, sama dengan true.

Dengan ===, tipe data diperiksa untuk memastikan dua variabel / objek / apa pun yang menggunakan tipe yang sama.

Jadi jika saya lakukan

if ($var === true)
{
    echo "var is true";
}

kondisi itu tidak akan benar, karena $var !== truehanya == true(jika Anda tahu apa yang saya maksud).

Mengapa Anda membutuhkan ini?

Sederhana - mari kita lihat salah satu fungsi PHP array_search()::

The array_search()Fungsi hanya pencarian untuk nilai dalam array, dan kembali kunci dari elemen nilai ditemukan di. Jika nilai tidak dapat ditemukan dalam array, ia mengembalikan palsu . Tapi, bagaimana jika Anda melakukan array_search()pada nilai yang disimpan dalam elemen pertama array (yang akan memiliki kunci array 0) .... array_search()fungsi akan mengembalikan 0 ... yang sama dengan false ..

Jadi, jika Anda melakukannya:

$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.
}

Jadi, apakah Anda melihat bagaimana ini bisa menjadi masalah sekarang?

Kebanyakan orang tidak menggunakan == falseketika memeriksa apakah suatu fungsi mengembalikan false. Sebaliknya, mereka menggunakan !. Tetapi sebenarnya, ini persis sama dengan menggunakan ==false, jadi jika Anda melakukannya:

$arr = array("name");
if (!array_search("name", $arr)) // This is the same as doing (array_search("name", $arr) == false)

Jadi untuk hal-hal seperti itu, Anda akan menggunakan ===gantinya, sehingga tipe data diperiksa.

Peter Mortensen
sumber
8

Salah satu contoh adalah bahwa atribut database bisa nol atau "":

$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
fico7489
sumber
7

php == adalah operator pembanding yang membandingkan nilai variabel. Tapi === membandingkan nilai dan tipe data.

Sebagai contoh,

<?php 
  $var1 = 10;
  $var2 = '10';

  if($var1 == $var2) {
    echo 'Variables are equal';
  } else {
    echo 'Variables are not equal';
  }
?>

Dalam hal ini output akan menjadi 'Variabel sama', meskipun tipe datanya berbeda.

Tetapi jika kita menggunakan === daripada ==, hasilnya adalah 'Variabel tidak sama'. Php pertama membandingkan nilai variabel dan kemudian tipe data. Di sini nilainya sama, tetapi tipe data berbeda.

2rahulsk
sumber
6

Diberikan x = 5

1) Operator: == sama dengan ". x == 8is false
2) Operator: === "sama dengan" (nilai dan tipe) x === 5benar, x === "5"salah

Mannusanghi
sumber
3
$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

Berhati-hatilah. Ini masalah yang terkenal.

// '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...
}
Seph
sumber
3

Singkatnya, === bekerja dengan cara yang sama seperti yang dilakukan== di sebagian besar bahasa pemrograman lainnya.

PHP memungkinkan Anda untuk membuat perbandingan yang tidak terlalu masuk akal. Contoh:

$y = "wauv";
$x = false;
if ($x == $y)
    ...

Meskipun ini memungkinkan untuk beberapa "jalan pintas" yang menarik Anda harus berhati-hati karena fungsi yang mengembalikan sesuatu yang tidak seharusnya (seperti "kesalahan" bukan angka) tidak akan tertangkap, dan Anda akan bertanya-tanya apa yang terjadi.

Dalam PHP, == membandingkan nilai dan melakukan konversi tipe jika perlu (misalnya, string "12343sdfjskfjds" akan menjadi "12343" dalam perbandingan bilangan bulat). === akan membandingkan nilai DAN tipe dan akan mengembalikan false jika jenisnya tidak sama.

Jika Anda melihat di manual PHP, Anda akan melihat bahwa banyak fungsi mengembalikan "false" jika fungsi gagal, tetapi mereka mungkin mengembalikan 0 dalam skenario yang sukses, itulah sebabnya mereka merekomendasikan melakukan "if (function ()! == false) "untuk menghindari kesalahan.

Christian P.
sumber
1
Perlu dicatat bahwa selain "pintasan" tersebut, perilaku abnormal dari operator == telah diketahui membuka celah keamanan, misalnya forum PHP populer di mana dimungkinkan untuk mengatur nilai hash kata sandi cookie menjadi true, mengelak. validasi if (databasehash == cookiehash).
David
3

Beberapa contoh

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

== Membandingkan nilainya saja, tidak akan mengganggu tentang tipe data

vs.

=== Membandingkan nilai dan tipe data

Mohit Tanwani
sumber
apa masalah dengan jawaban ini?
Mohit Tanwani
2

Anda akan menggunakan === untuk menguji apakah suatu fungsi atau variabel salah daripada hanya menyamakan ke false (nol atau string kosong).

$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;
}

Dalam hal ini strpos akan mengembalikan 0 yang akan sama dengan false dalam pengujian

if ($pos == false)

atau

if (!$pos)

yang bukan apa yang Anda inginkan di sini.

Stacey Richards
sumber
2

Adapun kapan harus menggunakan satu di atas yang lain, ambil misalnya fwrite()fungsi dalam PHP.

Fungsi ini menulis konten ke aliran file. Menurut PHP, " fwrite()mengembalikan jumlah byte yang ditulis, atau SALAH pada kesalahan." Jika Anda ingin menguji apakah pemanggilan fungsi berhasil, metode ini cacat:

if (!fwrite(stuff))
{
    log('error!');
}

Dapat mengembalikan nol (dan dianggap berhasil), dan kondisi Anda masih terpicu. Cara yang benar adalah:

if (fwrite(stuff) === FALSE)
{
    log('error!');
}
Mario
sumber
2

PHP adalah bahasa yang diketik secara longgar. Dengan menggunakan operator ganda sama dengan memungkinkan pengecekan variabel yang longgar.

Dengan memeriksa nilai secara longgar akan memungkinkan beberapa nilai yang sama, tetapi tidak sama, untuk disamakan sebagai sama:

  • ''
  • batal
  • Salah
  • 0

Semua nilai ini akan sama dengan menggunakan operator sama dengan ganda.

Cory Collier
sumber
1

Variabel memiliki tipe dan nilai.

  • $ var = "test" adalah string yang berisi "test"
  • $ var2 = 24 adalah nilai integer vhose adalah 24.

Saat Anda menggunakan variabel-variabel ini (dalam PHP), terkadang Anda tidak memiliki tipe yang baik. Misalnya, jika Anda melakukannya

if ($var == 1) {... do something ...}

PHP harus mengonversi ("untuk membuang") $ var ke integer. Dalam kasus ini, "$ var == 1" benar karena setiap string yang tidak kosong dilemparkan ke 1.

Saat menggunakan ===, Anda memeriksa bahwa nilai DAN JENIS THE sama, jadi "$ var === 1" salah.

Ini berguna, misalnya, ketika Anda memiliki fungsi yang dapat mengembalikan false (kesalahan) dan 0 (hasil):

if(myFunction() == false) { ... error on myFunction ... }

Kode ini salah seolah-olah myFunction()mengembalikan 0, ini dilemparkan ke false dan Anda tampaknya memiliki kesalahan. Kode yang benar adalah:

if(myFunction() === false) { ... error on myFunction ... }

karena tesnya adalah bahwa nilai kembali "adalah boolean dan salah" dan bukan "dapat dicor salah".

ofaurax
sumber
mengenai string yang tidak kosong, itu sebenarnya tidak benar. "a" == 0 BENAR.
nickf
1

The ===Operator seharusnya untuk membandingkan tepat konten kesetaraan sedangkan ==operator yang akan membandingkan kesetaraan semantik. Khususnya itu akan memaksa string ke angka.

Kesetaraan adalah subjek yang luas. Lihat artikel Wikipedia tentang kesetaraan .

kmkaplan
sumber
1
<?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);
?>
Sathish
sumber
1

Semua jawaban sejauh ini mengabaikan masalah berbahaya dengan ===. Telah dicatat secara sepintas, tetapi tidak ditekankan, bahwa integer dan double adalah tipe yang berbeda, jadi kode berikut:

$n = 1000;
$d = $n + 0.0e0;
echo '<br/>'. ( ($n ==  $d)?'equal' :'not equal' );
echo '<br/>'. ( ($n === $d)?'equal' :'not equal' );

memberi:

 equal
 not equal

Perhatikan bahwa ini BUKAN kasus "kesalahan pembulatan". Kedua angka tersebut persis sama hingga ke bit terakhir, tetapi mereka memiliki tipe yang berbeda.

Ini adalah masalah buruk karena program menggunakan === dapat berjalan dengan bahagia selama bertahun-tahun jika semua angka cukup kecil (di mana "cukup kecil" tergantung pada perangkat keras dan OS yang Anda jalankan). Namun, jika secara kebetulan, bilangan bulat kebetulan cukup besar untuk dikonversi menjadi dobel, tipenya diubah "selamanya" walaupun operasi berikutnya, atau banyak operasi, mungkin membawanya kembali ke nilai integer kecil. Dan, itu semakin buruk. Ia dapat menyebar - infeksi dua kali lipat dapat diteruskan ke apa pun yang disentuhnya, satu perhitungan pada satu waktu.

Di dunia nyata, ini mungkin menjadi masalah dalam program yang menangani tanggal di luar tahun 2038, misalnya. Pada saat ini, cap waktu UNIX (jumlah detik sejak 1970-01-01 00:00:00 UTC) akan membutuhkan lebih dari 32-bit, sehingga perwakilan mereka akan "secara ajaib" beralih untuk menggandakan pada beberapa sistem. Oleh karena itu, jika Anda menghitung perbedaan antara dua kali Anda mungkin berakhir dengan beberapa detik, tetapi sebagai ganda, bukan hasil bilangan bulat yang terjadi pada tahun 2017.

Saya pikir ini jauh lebih buruk daripada konversi antara string dan angka karena itu halus. Saya merasa mudah untuk melacak apa yang merupakan string dan apa itu angka, tetapi melacak jumlah bit dalam angka berada di luar jangkauan saya.

Jadi, dalam jawaban di atas ada beberapa tabel yang bagus, tetapi tidak ada perbedaan antara 1 (sebagai bilangan bulat) dan 1 (rangkap halus) dan 1.0 (rangkap jelas). Juga, saran yang harus selalu Anda gunakan === dan jangan pernah == tidak bagus karena === terkadang gagal di mana == berfungsi dengan baik. Juga, JavaScript tidak setara dalam hal ini karena hanya memiliki satu tipe angka (secara internal mungkin memiliki representasi bit-wise yang berbeda, tetapi tidak menyebabkan masalah untuk ===).

Saran saya - jangan gunakan keduanya. Anda perlu menulis fungsi perbandingan sendiri untuk benar-benar memperbaiki kekacauan ini.

David Walley
sumber
0

Ada dua perbedaan antara ==dan ===dalam array dan objek PHP yang saya pikir tidak disebutkan di sini; dua array dengan jenis kunci yang berbeda, dan objek.

Dua array dengan jenis kunci yang berbeda

Jika Anda memiliki larik dengan jenis kunci dan larik lain dengan jenis kunci yang berbeda, mereka sangat berbeda (yaitu menggunakan ===). Itu dapat menyebabkan jika Anda mengurutkan-array, dan mencoba untuk membandingkan array yang diurutkan dengan yang asli.

Misalnya, pertimbangkan array kosong. Pertama, kami mencoba mendorong beberapa indeks baru ke array tanpa jenis khusus. Contoh yang baik adalah array dengan string sebagai kunci. Sekarang jauh ke dalam contoh:

// Define an array
$arr = [];

// Adding unsorted keys
$arr["I"] = "we";
$arr["you"] = "you";
$arr["he"] = "they";

Sekarang, kami memiliki larik tidak-diurutkan-kunci (misalnya, 'dia' datang setelah 'Anda'). Pertimbangkan array yang sama, tetapi kami mengurutkan kuncinya berdasarkan abjad:

// Declare array
$alphabetArr = [];

// Adding alphabetical-sorted keys
$alphabetArr["I"] = "we";
$alphabetArr["he"] = "they";
$alphabetArr["you"] = "you";

Tip : Anda dapat mengurutkan array berdasarkan kunci menggunakan fungsi ksort () .

Sekarang Anda memiliki array lain dengan jenis kunci yang berbeda dari yang pertama. Jadi, kita akan membandingkannya:

$arr == $alphabetArr; // true
$arr === $alphabetArr; // false

Catatan : Ini mungkin jelas, tetapi membandingkan dua array berbeda menggunakan perbandingan ketat selalu hasilnya false. Namun, dua array sewenang-wenang mungkin sama dengan menggunakan ===atau tidak.

Anda akan mengatakan: "Perbedaan ini dapat diabaikan". Lalu saya katakan itu perbedaan dan harus dipertimbangkan dan dapat terjadi kapan saja. Seperti disebutkan di atas, pengurutan kunci dalam array adalah contoh yang bagus.

Benda

Perlu diingat, dua objek berbeda tidak pernah sama ketatnya . Contoh-contoh ini akan membantu:

$stdClass1 = new stdClass();
$stdClass2 = new stdClass();
$clonedStdClass1 = clone $stdClass1;

// Comparing
$stdClass1 == $stdClass2; // true
$stdClass1 === $stdClass2; // false
$stdClass1 == $clonedStdClass1; // true
$stdClass1 === $clonedStdClass1; // false

Catatan : Menetapkan objek ke variabel lain tidak membuat salinan - melainkan membuat referensi ke lokasi memori yang sama dengan objek. Lihat di sini .

Catatan : Pada PHP7, kelas anonim telah ditambahkan. Dari hasil, tidak ada perbedaan antara new class {}dan new stdClass()dalam tes di atas.

MAChitgarha
sumber