ประเภทการเล่นกลและ (เข้มงวด) มากกว่า / น้อยกว่าการเปรียบเทียบใน PHP


115

PHP มีชื่อเสียงในด้านการเล่นกลประเภทต่างๆ ฉันต้องยอมรับว่ามันทำให้ฉันสับสนและฉันมีช่วงเวลาที่ยากลำบากในการค้นหาสิ่งที่เป็นตรรกะ / พื้นฐานพื้นฐานในการเปรียบเทียบ

ตัวอย่างเช่นหาก$a > $bเป็นความจริงและ$b > $cเป็นความจริงก็ต้องหมายความว่า$a > $cเป็นเสมอจริงเกินไป?

ตามตรรกะพื้นฐานฉันจะตอบว่าใช่แต่ฉันงงว่าฉันไม่เชื่อใจ PHP ในเรื่องนี้ อาจจะมีคนยกตัวอย่างที่ไม่ใช่กรณีนี้?

นอกจากนี้ฉันยังสงสัยด้วยตัวดำเนินการที่เข้มงวดน้อยกว่าและเข้มงวดมากขึ้น (เนื่องจากความหมายของพวกเขาถูกอธิบายอย่างเคร่งครัดซึ่งฉันรู้ในอดีตจากการเปรียบเทียบความเท่าเทียมกันเท่านั้น) ว่ามันสร้างความแตกต่างใด ๆ หากสลับตัวถูกดำเนินการซ้ายและขวาด้วย ค่าไม่เท่ากันอย่างเคร่งครัด:

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

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

สำหรับชุดค่าผสมการเปรียบเทียบส่วนใหญ่ตัวดำเนินการเปรียบเทียบที่มากกว่า / น้อยกว่าเหล่านี้จะไม่ได้รับการจัดทำเป็นเอกสารดังนั้นการอ่านคู่มือจึงไม่เป็นประโยชน์ในกรณีนี้


ฉันเดาว่าคุณต้องการแก้ไขบรรทัดนั้นให้เป็น($a > $b) !== ($b < $a)?
Walter Tross

อาตกลงฉันเข้าใจผิด จะต้องแก้ไขคำตอบของฉันตามนั้น ตลกทุกคนที่เขียนบทความแทนคำตอบและไม่อ่านคำถามของคุณอย่างรอบคอบ ...
Walter Tross

คำตอบ:


208

ตัวดำเนินการเปรียบเทียบของ PHP เบี่ยงเบนไปจากคำจำกัดความของคอมพิวเตอร์ - วิทยาศาสตร์ในหลายวิธี:

ในการสร้างความสัมพันธ์ที่เท่าเทียมกัน ==จะต้องมีการสะท้อนกลับสมมาตรและสกรรมกริยา:

  • ==ตัวดำเนินการของ PHP ไม่สะท้อนกลับกล่าว$a == $aคือไม่เป็นจริงเสมอไป:

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

    หมายเหตุ: ความจริงที่ว่าเปรียบเทียบใด ๆ ที่เกี่ยวข้องกับการNANอยู่เสมอfalseคือไม่เฉพาะ PHP ได้รับคำสั่งจาก IEEE 754 Standard for Floating-Point Arithmetic ( ข้อมูลเพิ่มเติม )

  • PHP ของ==ผู้ประกอบการเป็นสมมาตรคือ$a == $bและ$b == $aมีความเสมอกัน

  • PHP ของ==ผู้ประกอบการคือไม่สกรรมกริยาคือจาก$a == $bและ$b == $cไม่ได้ดังต่อไปนี้$a == $c:

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

ในการสร้างคำสั่งบางส่วน <= / >=ต้องมีการสะท้อนกลับต่อต้านสมมาตรและสกรรมกริยา:

  • <=ตัวดำเนินการของ PHP ไม่สะท้อนกลับกล่าว$a <= $aคือไม่เป็นจริงเสมอไป (ตัวอย่างเช่นเดียวกับสำหรับ==)

  • <=ตัวดำเนินการของ PHP ไม่ต่อต้านสมมาตรกล่าวคือจาก$a <= $bและ$b <= $aไม่ปฏิบัติตาม$a == $b:

    var_dump(NAN <= "foo"); // bool(true)
    var_dump("foo" <= NAN); // bool(true)
    var_dump(NAN == "foo"); // bool(false)
  • <=โอเปอเรเตอร์ของ PHP ไม่ใช่สกรรมกริยากล่าวคือจาก$a <= $bและ$b <= $cไม่ปฏิบัติตาม$a <= $c(ตัวอย่างเช่นเดียวกับสำหรับ==)

  • พิเศษ: <=ตัวดำเนินการของ PHP ไม่รวมนั่นคือทั้งสองอย่าง$a <= $bและ$b <= $aอาจเป็นเท็จ:

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

ในการสร้างคำสั่งบางส่วนที่เข้มงวด < / >จะต้องไม่สะท้อนกลับไม่สมมาตรและสกรรมกริยา:

  • <ตัวดำเนินการของ PHP ไม่สามารถสะท้อนกลับได้กล่าว$a < $aคือไม่เป็นความจริง โปรดทราบว่านี่เป็นจริงเฉพาะใน PHP 5.4เท่านั้น ก่อนหน้านี้การประเมินเพื่อINF < INFtrue

  • <ตัวดำเนินการของ PHP ไม่สมมาตรกล่าวคือจาก$a < $bไม่ปฏิบัติตาม!($b < $a)(ตัวอย่างเช่นเดียวกับการ<=ไม่ต่อต้านสมมาตร)

  • <ตัวดำเนินการของ PHP ไม่เป็นสกรรมกริยากล่าวคือจาก$a < $bและ$b < $cไม่ปฏิบัติตาม$a < $c:

    var_dump(-INF < 0);    // bool(true)
    var_dump(0 < TRUE);    // bool(true)
    var_dump(-INF < TRUE); // bool(false)
  • เสริม: PHP ของ<ผู้ประกอบการคือไม่ trichotomousคือทั้งหมดของ $a < $b, $b < $aและ$a == $bสามารถเป็นเท็จ (ตัวอย่างเช่นเดียวกับ<=การที่จะไม่ทั้งหมด)

  • เสริม: PHP ของ<ผู้ประกอบการสามารถเป็นวงกลมคือมันเป็นไปได้ว่า$a < $b, $b < $cและ$c < $a:

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

    หมายเหตุ: ตัวอย่างข้างต้นแสดงข้อความแจ้ง "Object of class stdClass can't be Convert to double"

คุณสามารถค้นหากราฟที่ดีสำหรับผู้ประกอบการไม่กี่เปรียบเทียบ PHP ในPHP ความโศกเศร้า 52 - ผู้ประกอบการเปรียบเทียบ

เป็นบันทึกสุดท้ายผมอยากจะชี้ให้เห็นว่ามีสอง equalities ว่า PHP ไม่รับประกัน (ไม่เหมือนทุกอย่างสวยอื่น) สองสิ่งนี้ถือไว้เสมอเพียงเพราะคอมไพเลอร์ลดค่าหนึ่งเป็นอีกอันหนึ่ง:

($a > $b) == ($b < $a)
($a >= $b) == ($b <= $a)

2
ว้าวผู้มาเยือนที่ดี ดังนั้นจึงเป็นไปไม่ได้ที่จะกำหนดนิพจน์เชิงตรรกะด้วย PHP เช่นเดียว($a > $b) and ($b > $c)กับ$a > $cแม้ว่าในเอกสารจะระบุว่าผู้</ >โอเปอเรเตอร์กล่าวว่าเข้มงวด ?
hakre

26
ตัวดำเนินการ IMHO ปฏิบัติตามกฎทางคณิตศาสตร์ แต่เฉพาะเมื่อจัดการกับประเภทข้อมูลเดียวกัน การคัดเลือกประเภทเป็นสิ่งที่สร้างความสับสนให้กับที่นี่ (และในสถานการณ์อื่น ๆ ) เมื่อเปรียบเทียบตัวเลขและสตริงและการแปลงประเภทค่าพิเศษจะกระทำก่อนตัวดำเนินการดังนั้นตัวดำเนินการเปรียบเทียบที่พูดอย่างเคร่งครัดจึงไม่สับสนการแคสต์คือ ...
ivanhoe

6
@ ivanhoe011 ความจริงก็คือ: ทั้งสอง :) PHP กฎการเปรียบเทียบและ PHP กฎหล่อแตกต่างกันคุณไม่สามารถเพียงแค่บอกว่าเป็นเช่นเดียวกับ$a == $b (type) $a === (type) $bตัวอย่างง่ายๆก็คือ"15" == "0xf"แต่(int) "15" !== (int) "0xf". และทั้งกฎการเปรียบเทียบและการแคสต์ใน PHP นั้นบ้ามาก ^^
NikiC

3
@NikiC: (int)"0xf"ประเมินจำนวนเต็มดังนั้นแน่นอน0 0 !== 15การเปรียบเทียบในตัวอย่างนี้ทำงานตรงตามที่คาดไว้ มันคือการคัดเลือกนักแสดงที่ทำให้สับสนที่นี่ ฉันจะยอมรับ(INF < INF) === trueเป็นปัญหาการเปรียบเทียบของแท้ แต่เป็นกรณีพิเศษและได้รับการแก้ไขตามที่คุณระบุ คำตอบที่ดี .. +1
FtDRbwLXw6

1
ฉันไม่จำเป็นต้องผิดนักออกแบบ PHP สำหรับการตัดสินใจบางอย่างที่สมเหตุสมผลเกี่ยวกับการบีบบังคับประเภทในเวลานั้น ... แต่ฉันรู้สึกว่าควรสังเกตผลลัพธ์ของตัวเลือกการออกแบบเหล่านี้และตระหนักได้ทันทีว่าตัวเลือกนั้นผิด ตัวอย่างที่ชัดเจนที่สุดคือความคิดเห็นของ @ ravz
ชาด

88

มีไม่มี เข้มงวดเหมือนกันดำเนินการเปรียบเทียบ ( >==หรือ<==) ใน PHP (โดย PHP 5.6.14 อย่างน้อย)มีกี่วิธีที่จะ แต่การบังคับใช้การตรวจสอบชนิดอย่างเข้มงวดก่อนการตรวจสอบมหานคร / ล่าง:

  1. ตรวจสอบตัวแปรทั้งสองประเภทด้วย if (gettype($a) === gettype($b))
  2. บังคับประเภทการร่ายที่คุณต้องการเช่น if ((string)$a === (string)$b)
  3. บังคับประเภทการเล่นกลที่คุณต้องการเช่น if (($a . '') === ($b . ''))

โปรดทราบว่า:

  • ความแม่นยำของจุดลอยมี จำกัด
  • INFและNANเป็นประเภทfloatภายใต้
  • อินฟินิตี้บางตัวเท่ากับค่าอื่น ๆอินฟินิตี้ (ตั้งแต่ PHP 5.4)
  • สัญกรณ์ทางวิทยาศาสตร์eเป็นประเภทเสมอfloatและไม่มีintegerแม้ว่าตัวเลขจะน้อย
  • จำนวนเต็ม PHP_INT_MAXถูกแปลงเป็นfloat
  • ลอยอยู่เหนือขอบเขตของระบบได้รับ INFค่า
  • ตัวแปรที่ไม่ได้กำหนดเป็นประเภทและมูลค่า NULL
  • จำนวนเต็มนำหน้าด้วย 0จะถูกแปลงจากฐานแปดเป็นฐานสิบ (ตามแบบแผน)
  • การแปลงสตริงที่มีจำนวนเต็มโดยนำหน้า0 ไปสู่จำนวนเต็มจะนำหน้า0

รายการการเปรียบเทียบที่แปลกใหม่:

ที่แปลกมาก:
     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  ลอย (NAN) ลอย (-INF) เท็จเท็จเท็จเท็จเท็จ
  ลอย (NAN) ลอย (0) เท็จเท็จเท็จเท็จเท็จ
  ลอย (NAN) ลอย (1) เท็จเท็จเท็จเท็จเท็จ
  float (NAN) float (INF) เท็จเท็จเท็จเท็จเท็จ
  float (NAN) float (NAN) เท็จเท็จเท็จเท็จเท็จ
  float (NAN) int (-1) เท็จเท็จเท็จเท็จเท็จ
  float (NAN) int (0) เท็จเท็จเท็จเท็จเท็จ
  float (NAN) int (1) เท็จเท็จเท็จเท็จเท็จ

เท่ากัน แต่ไม่เหมือนกัน:

     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  อาร์เรย์ NULL (NULL) () เท็จจริงจริงจริงเท็จ
  บูล NULL (NULL) (เท็จ) เท็จจริงจริงจริงเท็จ
  NULL (NULL) ลอย (0) เท็จจริงจริงจริงเท็จ
  NULL (NULL) int (0) เท็จจริงจริงจริงเท็จ
  NULL (NULL) str ('') เท็จจริงจริงจริงเท็จ
   อาร์เรย์ () บูล (เท็จ) เท็จจริงจริงจริงเท็จ
 บูล (เท็จ) ลอย (0) เท็จจริงจริงจริงเท็จ
 บูล (เท็จ) int (0) เท็จจริงจริงจริงเท็จ
   str ('') บูล (เท็จ) เท็จจริงจริงจริงเท็จ
 บูล (เท็จ) str ('0') เท็จจริงจริงจริงเท็จ
 ลอย (-INF) บูล (จริง) เท็จจริงจริงจริงเท็จ
  บูล (จริง) ลอย (1) เท็จจริงจริงจริงเท็จ
  ลอย (INF) บูล (จริง) เท็จจริงจริงจริงเท็จ
  ลอย (NAN) บูล (จริง) เท็จจริงจริงจริงเท็จ
  บูล (จริง) int (-1) เท็จจริงจริงจริงเท็จ
  บูล (จริง) int (1) เท็จจริงจริงจริงเท็จ
  บูล (true) str ("\ 0") เท็จจริงจริงจริงเท็จ
  บูล (จริง) str ('+') เท็จจริงจริงจริงเท็จ
  บูล (จริง) str ('-') เท็จจริงจริงจริงเท็จ
  บูล (true) str ('01 ') เท็จจริงจริงจริงเท็จ
  บูล (จริง) str ('1') เท็จจริงจริงจริงเท็จ
  บูล (จริง) str ('เท็จ') เท็จจริงจริงจริงเท็จ
 str ('text') บูล (จริง) เท็จจริงจริงเท็จจริง
 str ('จริง') บูล (จริง) เท็จจริงจริงเท็จจริง
    int (0) float (0) เท็จจริงจริงจริงเท็จ
  str ("\ 0") ลอย (0) เท็จจริงจริงจริงเท็จ
   str ('') ลอย (0) เท็จจริงจริงจริงเท็จ
   str ('+') ลอย (0) เท็จจริงจริงจริงเท็จ
   str ('-') ลอย (0) เท็จจริงจริงจริงเท็จ
   str ('0') ลอย (0) เท็จจริงจริงจริงเท็จ
 str ('เท็จ') ลอย (0) เท็จจริงจริงจริงเท็จ
 str ('text') ลอย (0) เท็จจริงจริงจริงเท็จ
 str ('จริง') ลอย (0) เท็จจริงจริงจริงเท็จ
    int (1) float (1) เท็จจริงจริงจริงเท็จ
   float (1) str ('01 ') เท็จจริงจริงจริงเท็จ
   ลอย (1) str ('1') เท็จจริงจริงจริงเท็จ
  str ("\ 0") int (0) เท็จจริงจริงจริงเท็จ
   str ('') int (0) เท็จจริงจริงจริงเท็จ
   str ('+') int (0) เท็จจริงจริงจริงเท็จ
   str ('-') int (0) เท็จจริงจริงจริงเท็จ
    int (0) str ('0') เท็จจริงจริงจริงเท็จ
 str ('false') int (0) เท็จจริงจริงจริงเท็จ
 str ('text') int (0) เท็จจริงจริงจริงเท็จ
 str ('true') int (0) เท็จจริงจริงจริงเท็จ
    int (1) str ('01 ') เท็จจริงจริงจริงเท็จ
    int (1) str ('1') เท็จจริงจริงจริงเท็จ
   str ('1') str ('01 ') เท็จจริงจริงจริงเท็จ

ต่ำกว่าและมากกว่าในเวลาเดียวกัน?

     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  float (NAN) str ("\ 0") จริงจริงจริงเท็จเท็จ
  float (NAN) str ('') จริงจริงจริงเท็จเท็จ
  float (NAN) str ('+') จริงจริงจริงเท็จเท็จ
  float (NAN) str ('-') จริงจริงจริงเท็จเท็จ
  float (NAN) str ('0') จริงจริงจริงเท็จเท็จ
  float (NAN) str ('01 ') จริงจริงจริงเท็จเท็จ
  float (NAN) str ('1') จริงจริงจริงเท็จเท็จ
  float (NAN) str ('false') จริงจริงจริงเท็จเท็จ
  float (NAN) str ('text') จริงจริงจริงเท็จเท็จ
  float (NAN) str ('true') จริงจริงจริงเท็จเท็จ

เท่ากันและเหมือนกัน:

     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  NULL (โมฆะ) NULL (NULL) เท็จจริงจริงจริงจริง
 ลอย (-INF) ลอย (-INF) เท็จจริงจริงจริงจริง
  float (INF) float (INF) เท็จจริงจริงจริงจริง

ต่ำกว่าหรือมากกว่า:

     $ a VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  NULL (NULL) บูล (จริง) เท็จจริงเท็จเท็จเท็จ
 float (-INF) NULL (NULL) จริงเท็จจริงเท็จเท็จ
  NULL (NULL) ลอย (1) เท็จจริงเท็จเท็จเท็จ
  float (INF) NULL (NULL) จริงเท็จจริงเท็จเท็จ
  float (NAN) NULL (NULL) จริงเท็จจริงเท็จเท็จ
  NULL (NULL) int (-1) จริงเท็จจริงเท็จเท็จ
  NULL (NULL) int (1) จริงเท็จจริงเท็จเท็จ
  NULL (NULL) str ("\ 0") เท็จจริงเท็จเท็จเท็จ
  NULL (NULL) str ('+') เท็จจริงเท็จเท็จเท็จ
  NULL (NULL) str ('-') เท็จจริงเท็จเท็จเท็จ
  NULL (NULL) str ('0') เท็จจริงเท็จเท็จเท็จ
  NULL (NULL) str ('01 ') เท็จจริงเท็จเท็จเท็จ
  NULL (NULL) str ('1') เท็จจริงเท็จเท็จเท็จ
  NULL (NULL) str ('เท็จ') เท็จจริงเท็จเท็จเท็จ
  NULL (NULL) str ('text') เท็จจริงเท็จเท็จเท็จ
  NULL (NULL) str ('true') จริงเท็จจริงเท็จเท็จ
   อาร์เรย์ () บูล (จริง) เท็จจริงเท็จเท็จเท็จ
 float (-INF) array () เท็จจริงเท็จเท็จเท็จ
   อาร์เรย์ () float (0) จริงเท็จจริงเท็จเท็จ
   อาร์เรย์ () float (1) จริงเท็จจริงเท็จเท็จ
  float (INF) array () เท็จจริงเท็จเท็จเท็จ
  float (NAN) array () เท็จจริงเท็จเท็จเท็จ
   อาร์เรย์ () int (-1) จริงเท็จจริงเท็จเท็จ
   อาร์เรย์ () int (0) จริงเท็จจริงเท็จเท็จ
   อาร์เรย์ () int (1) จริงเท็จจริงเท็จเท็จ
   อาร์เรย์ () str ("\ 0") จริงเท็จจริงเท็จเท็จ
   str ('') array () เท็จจริงเท็จเท็จเท็จ
   อาร์เรย์ () str ('+') จริงเท็จจริงเท็จเท็จ
   อาร์เรย์ () str ('-') จริงเท็จจริงเท็จเท็จ
   อาร์เรย์ () str ('0') จริงเท็จจริงเท็จเท็จ
   อาร์เรย์ () str ('01 ') จริงเท็จจริงเท็จเท็จ
   อาร์เรย์ () str ('1') จริงเท็จจริงเท็จเท็จ
   อาร์เรย์ () str ('เท็จ') จริงเท็จจริงเท็จเท็จ
   อาร์เรย์ () str ('ข้อความ') จริงเท็จจริงเท็จเท็จ
   อาร์เรย์ () str ('จริง') จริงเท็จจริงเท็จเท็จ
  บูล (จริง) บูล (เท็จ) จริงเท็จจริงเท็จเท็จ
 float (-INF) bool (false) จริงเท็จจริงเท็จเท็จ
   ลอย (1) บูล (เท็จ) จริงเท็จจริงเท็จเท็จ
  float (INF) bool (false) จริงเท็จจริงเท็จเท็จ
  ลอย (NAN) บูล (เท็จ) จริงเท็จจริงเท็จเท็จ
 บูล (เท็จ) int (-1) เท็จจริงเท็จเท็จเท็จ
    int (1) bool (เท็จ) จริงเท็จจริงเท็จเท็จ
 บูล (เท็จ) str ("\ 0") จริงเท็จจริงเท็จเท็จ
 บูล (เท็จ) str ('+') จริงเท็จจริงเท็จเท็จ
 บูล (เท็จ) str ('-') จริงเท็จจริงเท็จเท็จ
 บูล (เท็จ) str ('01 ') จริงเท็จจริงเท็จเท็จ
   str ('1') บูล (เท็จ) จริงเท็จจริงเท็จเท็จ
 บูล (เท็จ) str ('เท็จ') จริงเท็จจริงเท็จเท็จ
 str ('text') บูล (เท็จ) จริงเท็จจริงเท็จเท็จ
 str ('จริง') บูล (เท็จ) จริงเท็จจริงเท็จเท็จ
  บูล (จริง) ลอย (0) จริงเท็จจริงเท็จเท็จ
  บูล (จริง) int (0) จริงเท็จจริงเท็จเท็จ
   str ('') bool (จริง) เท็จจริงเท็จเท็จเท็จ
  bool (จริง) str ('0') จริงเท็จจริงเท็จเท็จ
 ลอย (-INF) ลอย (0) จริงเท็จจริงเท็จเท็จ
 ลอย (-INF) ลอย (1) จริงเท็จจริงเท็จเท็จ
  float (INF) float (-INF) จริงเท็จจริงเท็จเท็จ
 float (-INF) int (-1) เท็จจริงเท็จเท็จเท็จ
 float (-INF) int (0) เท็จจริงเท็จเท็จเท็จ
 float (-INF) int (1) จริงเท็จจริงเท็จเท็จ
 ลอย (-INF) str ("\ 0") เท็จจริงเท็จเท็จเท็จ
 ลอย (-INF) str ('') จริงเท็จจริงเท็จเท็จ
 ลอย (-INF) str ('+') เท็จจริงเท็จเท็จเท็จ
 ลอย (-INF) str ('-') เท็จจริงเท็จเท็จเท็จ
 ลอย (-INF) str ('0') เท็จจริงเท็จเท็จเท็จ
 ลอย (-INF) str ('01 ') จริงเท็จจริงเท็จเท็จ
 ลอย (-INF) str ('1') จริงเท็จจริงเท็จเท็จ
 float (-INF) str ('false') เท็จจริงเท็จเท็จเท็จ
 float (-INF) str ('text') เท็จจริงเท็จเท็จเท็จ
 float (-INF) str ('true') จริงเท็จจริงเท็จเท็จ
   ลอย (1) ลอย (0) จริงเท็จจริงเท็จเท็จ
  float (INF) float (0) จริงเท็จจริงเท็จเท็จ
   float (0) int (-1) จริงเท็จจริงเท็จเท็จ
    int (1) float (0) จริงเท็จจริงเท็จเท็จ
   ลอย (0) str ('01 ') จริงเท็จจริงเท็จเท็จ
   str ('1') ลอย (0) จริงเท็จจริงเท็จเท็จ
  float (INF) float (1) จริงเท็จจริงเท็จเท็จ
   float (1) int (-1) จริงเท็จจริงเท็จเท็จ
   float (1) int (0) จริงเท็จจริงเท็จเท็จ
   ลอย (1) str ("\ 0") จริงเท็จจริงเท็จเท็จ
   str ('') ลอย (1) เท็จจริงเท็จเท็จเท็จ
   ลอย (1) str ('+') จริงเท็จจริงเท็จเท็จ
   ลอย (1) str ('-') จริงเท็จจริงเท็จเท็จ
   float (1) str ('0') จริงเท็จจริงเท็จเท็จ
   ลอย (1) str ('เท็จ') จริงเท็จจริงเท็จเท็จ
 str ('text') ลอย (1) เท็จจริงเท็จเท็จเท็จ
 str ('true') float (1) เท็จจริงเท็จเท็จเท็จ
  float (INF) int (-1) จริงเท็จจริงเท็จเท็จ
  float (INF) int (0) จริงเท็จจริงเท็จเท็จ
  float (INF) int (1) จริงเท็จจริงเท็จเท็จ
  float (INF) str ("\ 0") จริงเท็จจริงเท็จเท็จ
  float (INF) str ('') จริงเท็จจริงเท็จเท็จ
  float (INF) str ('+') จริงเท็จจริงเท็จเท็จ
  float (INF) str ('-') จริงเท็จจริงเท็จเท็จ
  float (INF) str ('0') จริงเท็จจริงเท็จเท็จ
  float (INF) str ('01 ') จริงเท็จจริงเท็จเท็จ
  float (INF) str ('1') จริงเท็จจริงเท็จเท็จ
  float (INF) str ('false') จริงเท็จจริงเท็จเท็จ
  float (INF) str ('text') จริงเท็จจริงเท็จเท็จ
  float (INF) str ('true') จริงเท็จจริงเท็จเท็จ
    int (0) int (-1) จริงเท็จจริงเท็จเท็จ
    int (1) int (-1) จริงเท็จจริงเท็จเท็จ
  str ("\ 0") int (-1) จริงเท็จจริงเท็จเท็จ
   str ('') int (-1) จริงเท็จจริงเท็จเท็จ
   str ('+') int (-1) จริงเท็จจริงเท็จเท็จ
   str ('-') int (-1) จริงเท็จจริงเท็จเท็จ
   str ('0') int (-1) จริงเท็จจริงเท็จเท็จ
   int (-1) str ('01 ') จริงเท็จจริงเท็จเท็จ
   str ('1') int (-1) จริงเท็จจริงเท็จเท็จ
 str ('false') int (-1) จริงเท็จจริงเท็จเท็จ
 str ('text') int (-1) จริงเท็จจริงเท็จเท็จ
 str ('true') int (-1) จริงเท็จจริงเท็จเท็จ
    int (1) int (0) จริงเท็จจริงเท็จเท็จ
    int (0) str ('01 ') จริงเท็จจริงเท็จเท็จ
   str ('1') int (0) จริงเท็จจริงเท็จเท็จ
    int (1) str ("\ 0") จริงเท็จจริงเท็จเท็จ
   str ('') int (1) จริงเท็จจริงเท็จเท็จ
    int (1) str ('+') จริงเท็จจริงเท็จเท็จ
    int (1) str ('-') จริงเท็จจริงเท็จเท็จ
    int (1) str ('0') จริงเท็จจริงเท็จเท็จ
    int (1) str ('false') จริงเท็จจริงเท็จเท็จ
 str ('text') int (1) จริงเท็จจริงเท็จเท็จ
 str ('true') int (1) จริงเท็จจริงเท็จเท็จ
   str ('') str ("\ 0") เท็จจริงเท็จเท็จเท็จ
   str ('+') str ("\ 0") จริงเท็จจริงเท็จเท็จ
   str ('-') str ("\ 0") จริงเท็จจริงเท็จเท็จ
  str ("\ 0") str ('0') เท็จจริงเท็จเท็จเท็จ
  str ("\ 0") str ('01 ') เท็จจริงเท็จเท็จเท็จ
   str ('1') str ("\ 0") จริงเท็จจริงเท็จเท็จ
 str ('false') str ("\ 0") จริงเท็จจริงเท็จเท็จ
 str ('text') str ("\ 0") จริงเท็จจริงเท็จเท็จ
 str ('true') str ("\ 0") จริงเท็จจริงเท็จเท็จ
   str ('') str ('+') จริงเท็จจริงเท็จเท็จ
   str ('') str ('-') จริงเท็จจริงเท็จเท็จ
   str ('') str ('0') จริงเท็จจริงเท็จเท็จ
   str ('') str ('01 ') จริงเท็จจริงเท็จเท็จ
   str ('') str ('1') จริงเท็จจริงเท็จเท็จ
   str ('') str ('false') จริงเท็จจริงเท็จเท็จ
   str ('') str ('text') เท็จจริงเท็จเท็จเท็จ
   str ('') str ('true') จริงเท็จจริงเท็จเท็จ
   str ('-') str ('+') จริงเท็จจริงเท็จเท็จ
   str ('+') str ('0') เท็จจริงเท็จเท็จเท็จ
   str ('+') str ('01 ') จริงเท็จจริงเท็จเท็จ
   str ('1') str ('+') จริงเท็จจริงเท็จเท็จ
 str ('false') str ('+') จริงเท็จจริงเท็จเท็จ
 str ('text') str ('+') จริงเท็จจริงเท็จเท็จ
 str ('true') str ('+') จริงเท็จจริงเท็จเท็จ
   str ('-') str ('0') เท็จจริงเท็จเท็จเท็จ
   str ('-') str ('01 ') จริงเท็จจริงเท็จเท็จ
   str ('1') str ('-') จริงเท็จจริงเท็จเท็จ
 str ('false') str ('-') จริงเท็จจริงเท็จเท็จ
 str ('text') str ('-') จริงเท็จจริงเท็จเท็จ
 str ('true') str ('-') จริงเท็จจริงเท็จเท็จ
   str ('0') str ('01 ') เท็จจริงเท็จเท็จเท็จ
   str ('1') str ('0') จริงเท็จจริงเท็จเท็จ
 str ('false') str ('0') จริงเท็จจริงเท็จเท็จ
 str ('text') str ('0') จริงเท็จจริงเท็จเท็จ
 str ('true') str ('0') จริงเท็จจริงเท็จเท็จ
 str ('false') str ('01 ') จริงเท็จจริงเท็จเท็จ
 str ('text') str ('01 ') จริงเท็จจริงเท็จเท็จ
 str ('true') str ('01 ') จริงเท็จจริงเท็จเท็จ
   str ('1') str ('false') เท็จจริงเท็จเท็จเท็จ
 str ('text') str ('1') จริงเท็จจริงเท็จเท็จ
 str ('true') str ('1') จริงเท็จจริงเท็จเท็จ
 str ('text') str ('false') จริงเท็จจริงเท็จเท็จ
 str ('true') str ('false') จริงเท็จจริงเท็จเท็จ
 str ('true') str ('text') จริงเท็จจริงเท็จเท็จ

$a > $b > $cปริศนาเมื่อ: $aไม่เกิน$c.

A <C: ลอย (NAN)> str ('a')> str ('')
A <C: float (NAN)> str ('a')> str ('1')
A <C: float (NAN)> str ('a')> str ('A')
A <C: ลอย (NAN)> str ('a')> str ('0')
A <C: ลอย (NAN)> str ('1')> str ('')
A <C: ลอย (NAN)> str ('1')> str ('0')
A <C: ลอย (NAN)> str ('A')> str ('')
A <C: float (NAN)> str ('A')> str ('1')
A <C: ลอย (NAN)> str ('A')> str ('0')
A <C: ลอย (NAN)> str ('0')> str ('')
A <C: str ('')> ลอย (NAN)> str ('a')
A <C: str ('')> ลอย (NAN)> str ('1')
A <C: str ('')> ลอย (NAN)> str ('A')
A <C: str ('')> ลอย (NAN)> str ('0')
A <C: str ('a')> str ('')> ลอย (NAN)
A <C: str ('a')> str ('1')> ลอย (NAN)
A <C: str ('a')> str ('A')> ลอย (NAN)
A <C: str ('a')> str ('0')> ลอย (NAN)
A <C: str ('0')> str ('')> ลอย (NAN)
A == C: bool (true)> str ('')> ลอย (NAN)
A == C: bool (จริง)> str ('')> ลอย (-INF)
A == C: บูล (จริง)> str ('')> int (-1)
A == C: bool (จริง)> str ('')> ลอย (-1)
A == C: บูล (จริง)> อาร์เรย์ ()> ลอย (NAN)
A == C: bool (true)> array ()> float (INF)
A == C: บูล (จริง)> อาร์เรย์ ()> ลอย (-INF)
A == C: bool (จริง)> array ()> str ('a')
A == C: บูล (จริง)> อาร์เรย์ ()> int (1)
A == C: bool (true)> array ()> float (1)
A == C: bool (จริง)> อาร์เรย์ ()> str ('1')
A == C: บูล (จริง)> อาร์เรย์ ()> str ('A')
A == C: บูล (จริง)> อาร์เรย์ ()> int (-1)
A == C: บูล (จริง)> อาร์เรย์ ()> ลอย (-1)
A == C: bool (จริง)> int (0)> ลอย (-INF)
A == C: บูล (จริง)> int (0)> int (-1)
A == C: bool (จริง)> int (0)> ลอย (-1)
A == C: bool (จริง)> str ('0')> ลอย (NAN)
A == C: bool (จริง)> str ('0')> ลอย (-INF)
A == C: บูล (จริง)> str ('0')> int (-1)
A == C: bool (จริง)> str ('0')> ลอย (-1)
A == C: bool (จริง)> ลอย (0)> ลอย (-INF)
A == C: bool (จริง)> ลอย (0)> int (-1)
A == C: bool (จริง)> ลอย (0)> ลอย (-1)
A == C: int (1)> str ('a')> str ('1')
A == C: int (1)> str ('A')> str ('1')
A == C: ลอย (1)> str ('a')> str ('1')
A == C: ลอย (1)> str ('A')> str ('1')
A == C: str ('a')> str ('1')> int (0)
A == C: str ('a')> str ('1')> ลอย (0)
A == C: str ('')> ลอย (-INF)> โมฆะ (NULL)
A == C: str ('')> ลอย (-INF)> บูล (เท็จ)
A == C: str ('')> int (-1)> โมฆะ (โมฆะ)
A == C: str ('')> int (-1)> บูล (เท็จ)
A == C: str ('')> float (-1)> NULL (โมฆะ)
A == C: str ('')> ลอย (-1)> บูล (เท็จ)
A == C: array ()> float (NAN)> NULL (โมฆะ)
A == C: array ()> float (NAN)> bool (false)
A == C: array ()> float (INF)> 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 (โมฆะ)
A == C: array ()> str ('a')> bool (เท็จ)
A == C: array ()> int (1)> NULL (โมฆะ)
A == C: array ()> int (1)> บูล (เท็จ)
A == C: array ()> float (1)> NULL (โมฆะ)
A == C: array ()> float (1)> bool (false)
A == C: array ()> str ('1')> NULL (โมฆะ)
A == C: array ()> str ('1')> บูล (เท็จ)
A == C: array ()> str ('A')> NULL (โมฆะ)
A == C: array ()> str ('A')> บูล (เท็จ)
A == C: array ()> str ('0')> NULL (โมฆะ)
A == C: array ()> int (-1)> NULL (โมฆะ)
A == C: array ()> int (-1)> บูล (เท็จ)
A == C: array ()> float (-1)> NULL (โมฆะ)
A == C: array ()> float (-1)> bool (false)
A == C: str ('')> ลอย (NAN)> บูล (เท็จ)
A == C: str ('')> ลอย (NAN)> โมฆะ (NULL)
A == C: str ('A')> str ('1')> int (0)
A == C: str ('A')> str ('1')> ลอย (0)
A == C: int (0)> ลอย (-INF)> โมฆะ (โมฆะ)
A == C: int (0)> ลอย (-INF)> บูล (เท็จ)
A == C: int (0)> int (-1)> NULL (โมฆะ)
A == C: int (0)> int (-1)> บูล (เท็จ)
A == C: int (0)> ลอย (-1)> โมฆะ (NULL)
A == C: int (0)> ลอย (-1)> บูล (เท็จ)
A == C: str ('0')> ลอย (NAN)> บูล (เท็จ)
A == C: str ('0')> ลอย (-INF)> บูล (เท็จ)
A == C: str ('0')> int (-1)> บูล (เท็จ)
A == C: str ('0')> ลอย (-1)> บูล (เท็จ)
A == C: float (0)> float (-INF)> NULL (NULL)
A == C: ลอย (0)> ลอย (-INF)> บูล (เท็จ)
A == C: float (0)> int (-1)> NULL (โมฆะ)
A == C: float (0)> int (-1)> bool (เท็จ)
A == C: float (0)> float (-1)> NULL (โมฆะ)
A == C: ลอย (0)> ลอย (-1)> บูล (เท็จ)
A === C: str ('0')> ลอย (NAN)> str ('0')
A === C: str ('')> ลอย (NAN)> str ('')
A === C: str ('a')> ลอย (NAN)> str ('a')
A === C: str ('1')> ลอย (NAN)> str ('1')
A === C: str ('A')> ลอย (NAN)> str ('A')

เปรียบเทียบสตริงสนุก ๆ : 'Queen' >'King' >'Jack' >'Ace'

ตรวจสอบตารางเปรียบเทียบประเภท PHP ที่ครอบคลุมคู่:

  • isset() และ is_null()
  • if() และ empty()
  • บูลีน==เทียบกับ===

ตรวจสอบความแตกต่างระหว่างเวอร์ชัน PHP ได้ที่ http://3v4l.org/MAfDu .


26
+1 นับประสา "ตาราง" ที่เลื่อนได้พร้อมส่วนหัวคอลัมน์คงที่ - แนวคิดที่ดี;)
hakre

จำเป็นต้องใช้ตัวดำเนินการที่เข้มงวดในการหล่อแบบหรือไม่? ฉันหมายความว่าคุณเคยเขียนif ( (string)$a===(string)$b )แต่มันไม่เหมือนกับif ( (string)$a==(string)$b )?
Voitcus

@Voitcus ใช่สำหรับทั้งประเภทหล่อ(string)1==(string)'01'-> bool(true)และสำหรับประเภท-เล่นปาหี่(1 . '')=='01'-> bool(true)ไม่ตรงเช่นเดียวกับ===เมื่อคุณจะได้รับbool(false)ทั้งสองบัญชี
CSᵠ

1
หนึ่ง nit-pick: ค่าฐานแปดไม่ได้ถูก "แปลงในการกำหนด" แต่จะถูกตีความโดยคอมไพเลอร์ซึ่งต้องเปลี่ยน ASCII ให้เป็นเลขฐานสองที่แท้จริง
IMSoP

INFINITY is equal to INFINITY which is mathematically incorrect!เป็นคำสั่งที่ถกเถียงกันอย่างเด็ดเดี่ยว นอกจากนี้โปรดทราบว่าNaNตามแบบแผนไม่มากกว่าน้อยกว่าหรือเท่ากับสิ่งใด ๆ ในภาษาโปรแกรมใด ๆ ที่ฉันรู้จัก
DaveRandom

22

หลังจากแก้ไขส่วนที่สองของคำถามของคุณแล้วฉันจะทิ้งคำตอบส่วนนั้นให้กับคนอื่น ๆ ฉันแค่อยากจะให้คำตอบที่น่าแปลกใจที่สุดสำหรับส่วนแรกของคำถามของคุณนั่นคือมีตัวอย่างของ<และ>ตัวดำเนินการที่อกรรมกริยาหรือไม่ นี่คือ

ทั้งหมดนี้คือtrue:

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

ถ้า<เป็นสกรรมกริยา ( $a < $b$b < $c$a < $c) บรรทัดสุดท้ายจะเป็น

"10" < "2"

แต่ PHP พยายามที่จะใจดี (?!) และตีความสตริงเป็นตัวเลขทุกครั้งที่ทำได้

ปรากฎว่าเนื่องจากความไม่เปลี่ยนแปลงข้างต้นsort()สามารถจัดเรียงองค์ประกอบเดียวกันเป็นลำดับที่แตกต่างกันขึ้นอยู่กับลำดับการป้อนข้อมูลแม้ว่าจะไม่มีองค์ประกอบสององค์ประกอบ== (และไม่มีองค์ประกอบใดเป็น NAN) ฉันชี้สิ่งนี้ในความคิดเห็นเพื่อเรียงลำดับ ()ซึ่งสาระสำคัญคือ:

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" )

1
ความคิดเห็นก่อนหน้านี้อ้างถึงส่วนหนึ่งของคำตอบ (เกี่ยวข้องกับส่วนที่สองของคำถาม) ที่ฉันได้ลบไปในขณะเดียวกัน
Walter Tross

ลบออกว่าตอนนี้;) และใหม่สุขsort()ตารางหยิบมันเป็นอย่างดีสำหรับผลกระทบในทางปฏิบัติเมื่อเขียนบล็อกที่เกี่ยวข้องกับการโพสต์ที่ยิ่งใหญ่ที่สุดราคา PHP ขอขอบคุณอีกครั้งสำหรับคำตอบของคุณ
hakre

หมายความว่าควรใช้usortทุกครั้งที่ทำได้หรือไม่?
Voitcus

2
@Voitcus: usort($arr, 'strcmp')ผมคิดว่าคุณหมายถึง งานนี้ (สตริงของหลักสูตร) sort($arr, SORT_STRING)แต่ของที่ดีที่สุดในการใช้งาน
Walter Tross

@WalterTross ฉันหมายถึงใช้ฟังก์ชันของคุณเองเสมอ (ไม่ใช่เฉพาะกับสตริง) เพื่อให้แน่ใจว่าถูกต้องเสมอ
Voitcus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.