Ketik-juggling dan (ketat) lebih besar / lebih kecil dari perbandingan di PHP

115

PHP terkenal dengan tipenya yang juggling. Saya harus mengakuinya membuat saya bingung, dan saya mengalami kesulitan untuk menemukan hal-hal dasar logis / fundamental dalam perbandingan.

Sebagai contoh: Jika $a > $bbenar dan $b > $cbenar, harus itu berarti bahwa $a > $cadalah selalu benar juga?

Mengikuti logika dasar, saya akan mengatakan ya namun saya bingung, saya tidak terlalu mempercayai PHP dalam hal ini. Mungkin seseorang dapat memberikan contoh dimana hal ini tidak terjadi?

Juga saya bertanya-tanya dengan operator yang ketat lebih rendah dari dan lebih ketat daripada (karena artinya dijelaskan secara ketat yang hanya saya ketahui di masa lalu dari perbandingan kesetaraan) jika ada bedanya jika operan kiri dan kanan ditukar dengan nilai yang sangat tidak sama:

# Precondition:
if ($a === $b) {
    throw new Exception(
       'Both are strictly equal - can not compare strictly for greater or smaller'
    );
}

($a > $b) !== ($b > $a)

Untuk sebagian besar dari semua kombinasi perbandingan jenis, operator perbandingan yang lebih besar / lebih kecil ini tidak didokumentasikan, jadi membaca manual tidak terlalu membantu dalam kasus ini.

hakre
sumber
Saya kira Anda ingin mengoreksi baris itu menjadi ($a > $b) !== ($b < $a)?
Walter Tross
ah, ok, jadi saya salah paham. Akan harus memperbaiki jawaban saya sesuai. Lucu semua orang yang menulis risalah alih-alih jawaban dan tidak membaca pertanyaan Anda dengan cermat ...
Walter Tross

Jawaban:

208

Operator perbandingan PHP menyimpang dari definisi ilmiah komputer dalam beberapa cara:

Untuk membentuk suatu hubungan ekivalensi == harus refleksif, simetris dan transitif:

  • PHP ==operator adalah tidak refleksif , yaitu $a == $atidak selalu benar:

    var_dump(NAN == NAN); // bool(false)

    Catatan: Fakta yang melibatkan perbandingan NAN selalu falsetidak spesifik untuk PHP. Ini diamanatkan oleh IEEE 754 Standard for Floating-Point Arithmetic ( info lebih lanjut ).

  • PHP == operator adalah simetris , yaitu $a == $bdan $b == $aselalu sama.

  • Operator PHP tidak== bersifat transitif , yaitu dari $a == $bdan $b == $ctidak tidak berikut $a == $c:

    var_dump(true == "a"); // bool(true)
    var_dump("a" == 0);    // bool(true)
    var_dump(true == 0);   // bool(false)

Untuk merupakan a tatanan parsial <= / >=harus refleksif, anti-simetris dan transitif:

  • PHP <= operator adalah tidak refleksif , yaitu $a <= $atidak selalu benar (Contoh sama seperti untuk ==).

  • PHP <=operator adalah tidak anti-simetris , yaitu dari $a <= $bdan$b <= $a tidak mengikuti $a == $b:

    var_dump(NAN <= "foo"); // bool(true)
    var_dump("foo" <= NAN); // bool(true)
    var_dump(NAN == "foo"); // bool(false)
  • PHP <=operator tidak transitif , yaitu dari$a <= $b dan $b <= $ctidak mengikuti $a <= $c(Contoh sama seperti untuk ==).

  • Ekstra: PHP <=operator adalah tidak keseluruhan , yaitu baik$a <= $b dan $b <= $adapat palsu:

    var_dump(new stdClass <= new DateTime); // bool(false)
    var_dump(new DateTime <= new stdClass); // bool(false)

Untuk merupakan a tatanan parsial yang ketat < / >harus tidak refleksif, asimetris, dan transitif:

  • Operator PHP <tidak refleksif , artinya $a < $atidak pernah benar. Perhatikan bahwa ini benar hanya pada PHP 5.4 . Sebelumnya INF < INFdievaluasi ke true.

  • PHP <operator adalah tidak asimetris , yaitu dari$a < $b tidak mengikuti !($b < $a)(Contoh sama seperti untuk <=tidak menjadi anti-simetris).

  • PHP <operator adalah tidak transitif , yaitu dari $a < $bdan $b < $ctidak mengikuti $a < $c:

    var_dump(-INF < 0);    // bool(true)
    var_dump(0 < TRUE);    // bool(true)
    var_dump(-INF < TRUE); // bool(false)
  • Ekstra: Operator PHP <adalah tidak trikotomi , yaitu semua $a < $b, $b < $adan $a == $bbisa salah (Contoh sama dengan <=tidak total).

  • Ekstra: Operator PHP <bisa melingkar , yaitu mungkin saja $a < $b, $b < $cdan $c < $a:

    var_dump(INF < []);           // bool(true)
    var_dump([] < new stdClass);  // bool(true)
    var_dump(new stdClass < INF); // bool(true)

    Catatan: Contoh di atas menampilkan pemberitahuan "Objek kelas stdClass tidak bisa diubah menjadi ganda".

Anda dapat menemukan beberapa grafik yang bagus untuk operator perbandingan PHP di PHP Sadness 52 - Operator perbandingan .

Sebagai catatan terakhir, saya ingin menunjukkan bahwa ada dua persamaan yang dijamin oleh PHP (tidak seperti yang lainnya). Keduanya selalu berlaku, hanya karena kompiler mengurangi satu sama lain:

($a > $b) == ($b < $a)
($a >= $b) == ($b <= $a)
NikiC
sumber
2
Wow, jawaban yang bagus. Jadi tidak mungkin untuk merumuskan ekspresi logis dengan PHP seperti ($a > $b) and ($b > $c)dengan $a > $cmeskipun dokumentasinya mengatakan bahwa </ >operator mengatakan mereka ketat ?
hakre
26
Operator IMHO memang mengikuti aturan matematika, tetapi hanya jika berurusan dengan tipe data yang sama. Jenis casting inilah yang benar-benar menciptakan kebingungan di sini (dan dalam banyak situasi lainnya). Ketika membandingkan angka dan string dan konversi jenis nilai khusus dilakukan sebelum operator, jadi operator perbandingan tegasnya tidak membingungkan, casting adalah ...
ivanhoe
6
@ ivanhoe011 Yang benar adalah: Keduanya :) Aturan perbandingan PHP dan aturan casting PHP berbeda , Anda tidak bisa begitu saja mengatakan bahwa $a == $bitu sama dengan (type) $a === (type) $b. Contoh sederhananya adalah itu "15" == "0xf", tetapi (int) "15" !== (int) "0xf". Dan perbandingan dan aturan casting di PHP benar-benar gila ^^
NikiC
3
@ NikiC: (int)"0xf"mengevaluasi ke integer 0, jadi tentu saja 0 !== 15. Perbandingan dalam contoh ini berperilaku persis seperti yang diharapkan. Pengecoranlah yang membingungkan di sini. Saya akui, (INF < INF) === trueini adalah masalah perbandingan yang asli, tetapi ini adalah kasus khusus, dan telah diselesaikan seperti yang Anda tunjukkan. Jawaban yang bagus .. +1
FtDRbwLXw6
1
Saya tidak selalu menyalahkan para perancang PHP untuk beberapa keputusan yang masuk akal tentang pemaksaan tipe pada saat itu ... tetapi saya merasa mereka seharusnya memperhatikan hasil dari pilihan desain ini dan segera menyadari bahwa pilihannya jelas salah. Contoh paling jelas adalah komentar @ ravz.
Chad
88

Tidak ada operator perbandingan identik yang ketat ( >==atau <==) di PHP (setidaknya dengan PHP 5.6.14) , tetapi ada beberapa cara untuk menerapkan pemeriksaan tipe yang ketat sebelum memeriksa Greater / Lower:

  1. Periksa kedua jenis variabel dengan if (gettype($a) === gettype($b))
  2. Paksa cor-cast yang Anda butuhkan misalnya. if ((string)$a === (string)$b)
  3. Paksa jenis-juggle yang Anda butuhkan misalnya. if (($a . '') === ($b . ''))

Perhatikan bahwa:

  • Presisi floating point terbatas
  • INFdan NANtipe di floatbawah
  • Beberapa Infinity sama dengan beberapa Infinity lainnya (sejak PHP 5.4)
  • Notasi ilmiah eselalu bertipe float, dan tidak pernah integersekalipun jumlahnya kecil
  • Bilangan bulat akan PHP_INT_MAXotomatis dikonversi kefloat
  • Mengapung di atas batas sistem mendapatkan INFnilainya
  • Variabel tak terdefinisi adalah tipe dan nilai NULL
  • Bilangan bulat yang diawali dengan 0dikonversi dari oktal ke desimal (menurut konvensi)
  • Konversi String yang berisi integer dengan awalan 0 ke integer strip di depan0

Daftar beberapa perbandingan eksotis:

Sangat aneh:
     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  float (NAN) float (-INF) salah salah salah salah salah salah
  float (NAN) float (0) salah salah salah salah salah salah
  float (NAN) float (1) salah salah salah salah salah salah
  float (NAN) float (INF) salah salah salah salah salah salah
  float (NAN) float (NAN) salah salah salah salah salah salah
  float (NAN) int (-1) salah salah salah salah salah salah
  float (NAN) int (0) false false false false false false
  float (NAN) int (1) false false false false false false

Sama tapi tidak identik:

     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  NULL (NULL) array () false false true true true false
  NULL (NULL) bool (false) salah salah benar benar benar salah
  NULL (NULL) float (0) salah salah benar benar benar salah
  NULL (NULL) int (0) false salah benar benar benar salah
  NULL (NULL) str ('') salah salah benar benar benar salah
   array () bool (false) salah salah benar benar benar salah
 bool (salah) float (0) salah salah benar benar benar salah
 bool (false) int (0) false salah benar benar benar salah
   str ('') bool (salah) salah salah benar benar benar salah
 bool (salah) str ('0') salah salah benar benar benar salah
 float (-INF) bool (benar) salah salah benar benar benar salah
  bool (benar) float (1) salah salah benar benar benar salah
  float (INF) bool (benar) salah salah benar benar benar salah
  float (NAN) bool (benar) salah salah benar benar benar salah
  bool (benar) int (-1) salah salah benar benar benar salah
  bool (benar) int (1) salah salah benar benar benar salah
  bool (benar) str ("\ 0") salah salah benar benar benar salah
  bool (benar) str ('+') salah salah benar benar benar salah
  bool (benar) str ('-') salah salah benar benar benar salah
  bool (benar) str ('01 ') salah salah benar benar benar salah
  bool (benar) str ('1') salah salah benar benar benar salah
  bool (benar) str ('salah') salah salah benar benar benar salah
 str ('text') bool (true) false false true true true false
 str ('benar') bool (benar) salah salah benar benar benar salah
    int (0) float (0) salah salah benar benar benar benar salah
  str ("\ 0") float (0) salah salah benar benar benar salah
   str ('') float (0) salah salah benar benar benar salah
   str ('+') float (0) salah salah benar benar benar salah
   str ('-') float (0) salah salah benar benar benar salah
   str ('0') float (0) salah salah benar benar benar salah
 str ('false') float (0) false salah benar benar benar salah
 str ('text') float (0) salah salah benar benar benar salah
 str ('benar') float (0) salah salah benar benar benar salah
    int (1) float (1) false salah benar benar benar benar salah
   float (1) str ('01 ') false salah benar benar benar salah
   float (1) str ('1') salah salah benar benar benar salah
  str ("\ 0") int (0) salah salah benar benar benar salah
   str ('') int (0) salah salah benar benar benar benar salah
   str ('+') int (0) false false true true true false
   str ('-') int (0) salah salah benar benar benar salah
    int (0) str ('0') salah salah benar benar benar salah
 str ('false') int (0) false false true true true false
 str ('text') int (0) false false true true true false
 str ('true') int (0) false false true true true false
    int (1) str ('01 ') false false true true true false
    int (1) str ('1') salah salah benar benar benar salah
   str ('1') str ('01 ') false salah benar benar benar salah

Lebih Rendah dan Lebih Besar pada saat bersamaan?

     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  float (NAN) str ("\ 0") benar benar benar benar salah salah
  float (NAN) str ('') benar benar benar benar salah salah
  float (NAN) str ('+') benar benar benar benar salah salah
  float (NAN) str ('-') benar benar benar benar salah salah
  float (NAN) str ('0') benar benar benar benar salah salah
  float (NAN) str ('01 ') benar benar benar benar salah salah
  float (NAN) str ('1') benar benar benar benar salah salah
  float (NAN) str ('false') benar benar benar benar salah salah
  float (NAN) str ('text') benar benar benar benar salah salah
  float (NAN) str ('true') true true true true false false

Sama DAN identik:

     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  NULL (NULL) NULL (NULL) salah salah benar benar benar benar
 float (-INF) float (-INF) salah salah benar benar benar benar
  float (INF) float (INF) salah salah benar benar benar benar

Lebih Rendah atau Lebih Besar:

     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  NULL (NULL) bool (benar) salah benar benar salah salah salah
 float (-INF) NULL (NULL) benar salah salah benar salah salah
  NULL (NULL) float (1) salah benar benar salah salah salah
  float (INF) NULL (NULL) benar salah salah benar salah salah
  float (NAN) NULL (NULL) benar salah salah benar salah salah
  NULL (NULL) int (-1) salah benar benar salah salah salah
  NULL (NULL) int (1) false benar benar salah salah salah
  NULL (NULL) str ("\ 0") salah benar benar salah salah salah
  NULL (NULL) str ('+') salah benar benar salah salah salah
  NULL (NULL) str ('-') salah benar benar salah salah salah
  NULL (NULL) str ('0') salah benar benar salah salah salah
  NULL (NULL) str ('01 ') false benar benar salah salah salah
  NULL (NULL) str ('1') salah benar benar salah salah salah
  NULL (NULL) str ('false') salah benar benar salah salah salah
  NULL (NULL) str ('text') false benar benar salah salah salah
  NULL (NULL) str ('true') salah benar benar salah salah salah
   array () bool (benar) salah benar benar salah salah salah salah
 float (-INF) array () salah benar benar salah salah salah salah
   array () float (0) benar salah salah benar salah salah
   array () float (1) benar salah salah benar salah salah
  float (INF) array () salah benar benar salah salah salah salah
  float (NAN) array () salah benar benar salah salah salah
   array () int (-1) benar salah salah benar salah salah
   array () int (0) benar salah salah benar salah salah
   array () int (1) benar salah salah benar salah salah
   array () str ("\ 0") benar salah salah benar salah salah
   str ('') array () salah benar benar salah salah salah salah
   array () str ('+') benar salah salah benar salah salah
   array () str ('-') benar salah salah benar salah salah
   array () str ('0') benar salah salah benar salah salah
   array () str ('01 ') benar salah salah benar salah salah
   array () str ('1') benar salah salah benar salah salah
   array () str ('false') benar salah salah benar salah salah
   array () str ('text') benar salah salah benar salah salah
   array () str ('true') benar salah salah benar salah salah
  bool (benar) bool (salah) benar salah salah benar salah salah
 float (-INF) bool (false) benar salah salah benar salah salah
   float (1) bool (false) benar salah salah benar salah salah
  float (INF) bool (false) benar salah salah benar salah salah
  float (NAN) bool (false) benar salah salah benar salah salah
 bool (false) int (-1) false benar benar salah salah salah
    int (1) bool (false) benar salah salah benar salah salah
 bool (salah) str ("\ 0") salah benar benar salah salah salah
 bool (salah) str ('+') salah benar benar salah salah salah
 bool (salah) str ('-') salah benar benar salah salah salah
 bool (false) str ('01 ') false benar benar salah salah salah
   str ('1') bool (false) benar salah salah benar salah salah
 bool (salah) str ('salah') salah benar benar salah salah salah
 str ('text') bool (false) benar salah salah benar salah salah
 str ('true') bool (false) benar salah salah benar salah salah
  bool (benar) float (0) benar salah salah benar salah salah
  bool (benar) int (0) benar salah salah benar salah salah
   str ('') bool (benar) salah benar benar salah salah salah salah
  bool (benar) str ('0') benar salah salah benar salah salah
 float (-INF) float (0) salah benar benar salah salah salah
 float (-INF) float (1) salah benar benar salah salah salah
  float (INF) float (-INF) benar salah salah benar salah salah
 float (-INF) int (-1) salah benar benar salah salah salah
 float (-INF) int (0) salah benar benar salah salah salah salah
 float (-INF) int (1) false true true false false false
 float (-INF) str ("\ 0") salah benar benar salah salah salah
 float (-INF) str ('') salah benar benar salah salah salah
 float (-INF) str ('+') salah benar benar salah salah salah
 float (-INF) str ('-') salah benar benar salah salah salah
 float (-INF) str ('0') salah benar benar salah salah salah
 float (-INF) str ('01 ') salah benar benar salah salah salah
 float (-INF) str ('1') salah benar benar salah salah salah
 float (-INF) str ('false') salah benar benar salah salah salah
 float (-INF) str ('text') false benar benar salah salah salah
 float (-INF) str ('true') false benar benar salah salah salah
   float (1) float (0) benar salah salah benar salah salah
  float (INF) float (0) benar salah salah benar salah salah
   float (0) int (-1) benar salah salah benar salah salah
    int (1) float (0) benar salah salah benar salah salah
   float (0) str ('01 ') salah benar benar salah salah salah salah
   str ('1') float (0) benar salah salah benar salah salah
  float (INF) float (1) benar salah salah benar salah salah
   float (1) int (-1) benar salah salah benar salah salah
   float (1) int (0) benar salah salah benar salah salah
   float (1) str ("\ 0") benar salah salah benar salah salah
   str ('') float (1) salah benar benar salah salah salah
   float (1) str ('+') benar salah salah benar salah salah
   float (1) str ('-') benar salah salah benar salah salah
   float (1) str ('0') benar salah salah benar salah salah
   float (1) str ('false') benar salah salah benar salah salah
 str ('text') float (1) salah benar benar salah salah salah
 str ('benar') float (1) salah benar benar salah salah salah
  float (INF) int (-1) benar salah salah benar salah salah
  float (INF) int (0) benar salah salah benar salah salah
  float (INF) int (1) benar salah salah benar salah salah
  float (INF) str ("\ 0") benar salah salah benar salah salah
  float (INF) str ('') benar salah salah benar salah salah
  float (INF) str ('+') benar salah salah benar salah salah
  float (INF) str ('-') benar salah salah benar salah salah
  float (INF) str ('0') benar salah salah benar salah salah
  float (INF) str ('01 ') benar salah salah benar salah salah
  float (INF) str ('1') benar salah salah benar salah salah
  float (INF) str ('false') benar salah salah benar salah salah
  float (INF) str ('text') benar salah salah benar salah salah
  float (INF) str ('true') benar salah salah benar salah salah
    int (0) int (-1) benar salah salah benar salah salah
    int (1) int (-1) benar salah salah benar salah salah
  str ("\ 0") int (-1) benar salah salah benar salah salah
   str ('') int (-1) benar salah salah benar salah salah
   str ('+') int (-1) benar salah salah benar salah salah
   str ('-') int (-1) benar salah salah benar salah salah
   str ('0') int (-1) benar salah salah benar salah salah
   int (-1) str ('01 ') false true true false false false
   str ('1') int (-1) benar salah salah benar salah salah
 str ('false') int (-1) true false false true false false
 str ('text') int (-1) benar salah salah benar salah salah
 str ('true') int (-1) true false false true false false
    int (1) int (0) benar salah salah benar salah salah
    int (0) str ('01 ') salah benar benar salah salah salah salah
   str ('1') int (0) benar salah salah benar salah salah
    int (1) str ("\ 0") benar salah salah benar salah salah
   str ('') int (1) salah benar benar salah salah salah salah
    int (1) str ('+') benar salah salah benar salah salah
    int (1) str ('-') benar salah salah benar salah salah
    int (1) str ('0') benar salah salah benar salah salah
    int (1) str ('false') benar salah salah benar salah salah
 str ('text') int (1) false benar benar salah salah salah
 str ('benar') int (1) salah benar benar salah salah salah salah
   str ('') str ("\ 0") salah benar benar salah salah salah
   str ('+') str ("\ 0") benar salah salah benar salah salah
   str ('-') str ("\ 0") benar salah salah benar salah salah
  str ("\ 0") str ('0') salah benar benar salah salah salah
  str ("\ 0") str ('01 ') salah benar benar salah salah salah
   str ('1') str ("\ 0") benar salah salah benar salah salah
 str ('false') str ("\ 0") benar salah salah benar salah salah
 str ('text') str ("\ 0") benar salah salah benar salah salah
 str ('true') str ("\ 0") benar salah salah benar salah salah
   str ('') str ('+') salah benar benar salah salah salah
   str ('') str ('-') salah benar benar salah salah salah
   str ('') str ('0') salah benar benar salah salah salah
   str ('') str ('01 ') salah benar benar salah salah salah
   str ('') str ('1') salah benar benar salah salah salah
   str ('') str ('false') salah benar benar salah salah salah
   str ('') str ('text') salah benar benar salah salah salah
   str ('') str ('true') false benar benar salah salah salah
   str ('-') str ('+') benar salah salah benar salah salah
   str ('+') str ('0') salah benar benar salah salah salah
   str ('+') str ('01 ') salah benar benar salah salah salah
   str ('1') str ('+') benar salah salah benar salah salah
 str ('false') str ('+') true false false true false false
 str ('text') str ('+') true false false true false false
 str ('true') str ('+') true false false true false false
   str ('-') str ('0') salah benar benar salah salah salah
   str ('-') str ('01 ') salah benar benar salah salah salah
   str ('1') str ('-') benar salah salah benar salah salah
 str ('false') str ('-') benar salah salah benar salah salah
 str ('text') str ('-') benar salah salah benar salah salah
 str ('benar') str ('-') benar salah salah benar salah salah
   str ('0') str ('01 ') salah benar benar salah salah salah
   str ('1') str ('0') benar salah salah benar salah salah
 str ('false') str ('0') true false false true false false
 str ('text') str ('0') benar salah salah benar salah salah
 str ('true') str ('0') true false false true false false
 str ('false') str ('01 ') benar salah salah benar salah salah
 str ('text') str ('01 ') benar salah salah benar salah salah
 str ('true') str ('01 ') true false false true false false
   str ('1') str ('false') salah benar benar salah salah salah
 str ('text') str ('1') benar salah salah benar salah salah
 str ('benar') str ('1') benar salah salah benar salah salah
 str ('text') str ('false') benar salah salah benar salah salah
 str ('true') str ('false') benar salah salah benar salah salah
 str ('true') str ('text') benar salah salah benar salah salah

$a > $b > $cTeka-teki ketika: $atidak lebih dari $c.

A <C: float (NAN)> str ('a')> str ('')
A <C: float (NAN)> str ('a')> str ('1')
A <C: float (NAN)> str ('a')> str ('A')
A <C: float (NAN)> str ('a')> str ('0')
A <C: float (NAN)> str ('1')> str ('')
A <C: float (NAN)> str ('1')> str ('0')
A <C: float (NAN)> str ('A')> str ('')
A <C: float (NAN)> str ('A')> str ('1')
A <C: float (NAN)> str ('A')> str ('0')
A <C: float (NAN)> str ('0')> str ('')
A <C: str ('')> float (NAN)> str ('a')
A <C: str ('')> float (NAN)> str ('1')
A <C: str ('')> float (NAN)> str ('A')
A <C: str ('')> float (NAN)> str ('0')
A <C: str ('a')> str ('')> float (NAN)
A <C: str ('a')> str ('1')> float (NAN)
A <C: str ('a')> str ('A')> float (NAN)
A <C: str ('a')> str ('0')> float (NAN)
A <C: str ('0')> str ('')> float (NAN)
A == C: bool (true)> str ('')> float (NAN)
A == C: bool (true)> str ('')> float (-INF)
A == C: bool (true)> str ('')> int (-1)
A == C: bool (true)> str ('')> float (-1)
A == C: bool (true)> array ()> float (NAN)
A == C: bool (true)> array ()> float (INF)
A == C: bool (true)> array ()> float (-INF)
A == C: bool (true)> array ()> str ('a')
A == C: bool (true)> array ()> int (1)
A == C: bool (true)> array ()> float (1)
A == C: bool (true)> array ()> str ('1')
A == C: bool (true)> array ()> str ('A')
A == C: bool (true)> array ()> int (-1)
A == C: bool (true)> array ()> float (-1)
A == C: bool (true)> int (0)> float (-INF)
A == C: bool (true)> int (0)> int (-1)
A == C: bool (true)> int (0)> float (-1)
A == C: bool (true)> str ('0')> float (NAN)
A == C: bool (true)> str ('0')> float (-INF)
A == C: bool (true)> str ('0')> int (-1)
A == C: bool (true)> str ('0')> float (-1)
A == C: bool (true)> float (0)> float (-INF)
A == C: bool (true)> float (0)> int (-1)
A == C: bool (true)> float (0)> float (-1)
A == C: int (1)> str ('a')> str ('1')
A == C: int (1)> str ('A')> str ('1')
A == C: float (1)> str ('a')> str ('1')
A == C: float (1)> str ('A')> str ('1')
A == C: str ('a')> str ('1')> int (0)
A == C: str ('a')> str ('1')> float (0)
A == C: str ('')> float (-INF)> NULL (NULL)
A == C: str ('')> float (-INF)> bool (false)
A == C: str ('')> int (-1)> NULL (NULL)
A == C: str ('')> int (-1)> bool (false)
A == C: str ('')> float (-1)> NULL (NULL)
A == C: str ('')> float (-1)> bool (false)
A == C: array ()> float (NAN)> NULL (NULL)
A == C: array ()> float (NAN)> bool (false)
A == C: array ()> float (INF)> NULL (NULL)
A == C: array ()> float (INF)> bool (false)
A == C: array ()> float (-INF)> NULL (NULL)
A == C: array ()> float (-INF)> bool (false)
A == C: array ()> str ('a')> NULL (NULL)
A == C: array ()> str ('a')> bool (false)
A == C: array ()> int (1)> NULL (NULL)
A == C: array ()> int (1)> bool (false)
A == C: array ()> float (1)> NULL (NULL)
A == C: array ()> float (1)> bool (false)
A == C: array ()> str ('1')> NULL (NULL)
A == C: array ()> str ('1')> bool (false)
A == C: array ()> str ('A')> NULL (NULL)
A == C: array ()> str ('A')> bool (false)
A == C: array ()> str ('0')> NULL (NULL)
A == C: array ()> int (-1)> NULL (NULL)
A == C: array ()> int (-1)> bool (false)
A == C: array ()> float (-1)> NULL (NULL)
A == C: array ()> float (-1)> bool (false)
A == C: str ('')> float (NAN)> bool (false)
A == C: str ('')> float (NAN)> NULL (NULL)
A == C: str ('A')> str ('1')> int (0)
A == C: str ('A')> str ('1')> float (0)
A == C: int (0)> float (-INF)> NULL (NULL)
A == C: int (0)> float (-INF)> bool (false)
A == C: int (0)> int (-1)> NULL (NULL)
A == C: int (0)> int (-1)> bool (false)
A == C: int (0)> float (-1)> NULL (NULL)
A == C: int (0)> float (-1)> bool (false)
A == C: str ('0')> float (NAN)> bool (false)
A == C: str ('0')> float (-INF)> bool (false)
A == C: str ('0')> int (-1)> bool (false)
A == C: str ('0')> float (-1)> bool (false)
A == C: float (0)> float (-INF)> NULL (NULL)
A == C: float (0)> float (-INF)> bool (false)
A == C: float (0)> int (-1)> NULL (NULL)
A == C: float (0)> int (-1)> bool (false)
A == C: float (0)> float (-1)> NULL (NULL)
A == C: float (0)> float (-1)> bool (salah)
A === C: str ('0')> float (NAN)> str ('0')
A === C: str ('')> float (NAN)> str ('')
A === C: str ('a')> float (NAN)> str ('a')
A === C: str ('1')> float (NAN)> str ('1')
A === C: str ('A')> float (NAN)> str ('A')

Perbandingan senar menyenangkan: 'Queen' >'King' >'Jack' >'Ace'

Lihat juga tabel perbandingan tipe PHP yang mencakup pasangan:

  • isset() dan is_null()
  • if() dan empty()
  • boolean ==vs.===

Periksa perbedaan antara versi PHP langsung di. http://3v4l.org/MAfDu .

CSᵠ
sumber
26
+1 apalagi "tabel" yang dapat digulir dengan tajuk kolom tetap - ide bagus;)
hakre
Apakah seseorang perlu menggunakan operator yang ketat saat mengetik? Maksud saya, Anda telah menulis if ( (string)$a===(string)$b )tetapi bukankah ini persis sama if ( (string)$a==(string)$b )?
Voitcus
@Voitcus ya untuk kedua tipe pemain (string)1==(string)'01'-> bool(true)dan untuk tipe-juggle (1 . '')=='01'-> bool(true)tidak persis sama seperti ===saat Anda masuk bool(false)ke kedua akun
CSᵠ
1
Satu pilihan nit: nilai oktal tidak "diubah saat penugasan", nilai tersebut diinterpretasikan oleh kompiler, yang harus mengubah ASCII menjadi bilangan biner yang sebenarnya.
IMSoP
INFINITY is equal to INFINITY which is mathematically incorrect!adalah pernyataan yang bisa diperdebatkan. Juga perhatikan bahwa NaNmenurut konvensi tidak lebih dari, kurang dari atau sama dengan apa pun dalam bahasa pemrograman apa pun yang saya ketahui.
DaveRandom
22

Setelah Anda mengoreksi bagian kedua dari pertanyaan Anda, saya serahkan jawaban untuk bagian itu kepada yang lain. Saya hanya ingin memberikan jawaban yang paling mengejutkan untuk bagian pertama pertanyaan Anda, yaitu apakah ada contoh dari <dan> operator yang intransitif. Ini dia.

Ini semua adalah true:

"10" < "1a"
"1a" < "2"
"10" > "2"

Jika <transitif ( $a < $b$b < $c$a < $c), baris terakhir adalah

"10" < "2"

tetapi PHP mencoba untuk menjadi baik (?!) dan menafsirkan string sebagai angka kapanpun itu bisa.

Ternyata, karena intransitivitas di atas, sort()dapat mengurutkan elemen yang sama ke dalam urutan yang berbeda tergantung pada urutan masukannya, bahkan jika tidak ada dua elemen== (dan tidak ada elemen yang NAN). Saya menunjukkan ini dalam komentar ke sort () , yang intinya adalah:

sort(array("10", "1a", "2" )) => array("10", "1a", "2" )
sort(array("10", "2",  "1a")) => array("1a", "2",  "10")
sort(array("1a", "10", "2" )) => array("2",  "10", "1a")
sort(array("1a", "2",  "10")) => array("1a", "2",  "10")
sort(array("2",  "10", "1a")) => array("2",  "10", "1a")
sort(array("2",  "1a", "10")) => array("10", "1a", "2" )
Walter Tross
sumber
1
komentar sebelumnya mengacu pada bagian dari jawaban (terkait dengan bagian kedua dari pertanyaan) yang telah saya hapus sementara itu
Walter Tross
Hapus itu sekarang;) Dan sort()tabel baru yang bagus , pilih juga untuk implikasi praktis saat menulis posting blog terkait Nilai PHP Terbesar . Terima kasih sekali lagi atas jawaban Anda.
hakre
Apakah itu berarti bahwa seseorang harus menggunakannya usortjika memungkinkan?
Voitcus
2
@Voitcus: Saya rasa maksud Anda usort($arr, 'strcmp'). Ini berfungsi (untuk string, tentu saja), tetapi paling baik digunakan sort($arr, SORT_STRING).
Walter Tross
@WalterTross Maksud saya selalu menggunakan fungsi Anda sendiri (tidak hanya untuk string) untuk memastikannya selalu benar
Voitcus