== בודק אם שני ערכים שווים אחרי ש-PHP ממיר אותם לטיפוס משותף. === בודק שהם שווים וגם מאותו טיפוס. לכן 1 == "1" הוא true, בעוד 1 === "1" הוא false.
רוב הבאגים בהשוואות נובעים מכך ש-== ממיר משהו שלא ציפיתם לו. ברירת מחדל טובה היא === ו-!==, ומעבר ל-== רק כשאתם יודעים שאתם רוצים את ההמרה.
כל אופרטורי ההשוואה ב-PHP
| אופרטור | שם | אמת כאשר |
|---|---|---|
$a == $b | שוויון | שווים אחרי המרת טיפוסים |
$a === $b | זהות | שווים ומאותו טיפוס |
$a != $b, $a <> $b | אי שוויון | לא שווים אחרי המרת טיפוסים |
$a !== $b | אי זהות | לא שווים, או מטיפוסים שונים |
$a < $b, $a > $b | קטן מ, גדול מ | |
$a <= $b, $a >= $b | קטן או שווה, גדול או שווה | |
$a <=> $b | חללית | מחזיר -1, 0 או 1 |
טבלת השוואה רופפת ומחמירה
כל תא בטבלה הזו חושב על ידי PHP 8.3. עברו בין == ל-=== והקישו על תא כדי לראות את הביטוי. הרשת של == מלאה בהפתעות בשורות של null, "", "0" ו-[]; הרשת של === היא רק האלכסון שלה.
| $a == $b | true | false | 1 | 0 | -1 | "1" | "0" | "" | null | [] | "php" | "10" | "1e1" |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| true | |||||||||||||
| false | |||||||||||||
| 1 | |||||||||||||
| 0 | |||||||||||||
| -1 | |||||||||||||
| "1" | |||||||||||||
| "0" | |||||||||||||
| "" | |||||||||||||
| null | |||||||||||||
| [] | |||||||||||||
| "php" | |||||||||||||
| "10" | |||||||||||||
| "1e1" |
איך == משווה טיפוסים שונים
הכללים ש-PHP 8 פועלת לפיהם, בסדר שבו הם משנים בפועל:
- שתי מחרוזות מספריות מושוות כמספרים:
"10" == "1e1"וגם"1" == "01"הםtrue. - מספר ומחרוזת מספרית: המחרוזת הופכת למספר.
100 == "1e2"הואtrue. - מספר ומחרוזת לא מספרית: מאז PHP 8, המספר הופך למחרוזת והם מושווים כמחרוזות.
0 == "a"הואfalse(ב-PHP 7 זה היהtrue). - כל דבר מול bool: שני הצדדים מומרים ל-bool.
"a" == trueוגם[] == falseהםtrue. - null ומחרוזת:
nullהופך ל-"", ולכןnull == ""הואtrueאבלnull == "0"הואfalse. מול כל טיפוס אחר,nullמושווה כ-false. - שני מערכים: שווים כשיש להם אותם זוגות מפתח/ערך.
השורה האחרונה מראה למה השוואות סדר עם null נדירות שיש בהן היגיון: null הופך ל-false, -1 הופך ל-true, ו-false < true.
אי שוויון: != מול !==
!= ו-<> הם אותו אופרטור. !== הוא הגרסה המחמירה. ההבדל חשוב במיוחד עם פונקציות שמחזירות 0 או false, כמו strpos:
0 != false הוא false כי 0 מומר ל-false. 0 !== false הוא true כי int הוא לא bool. אותה מלכודת קיימת ב-array_search וב-in_array בלי הדגל המחמיר שלה.
השוואת מחרוזות
< ו-> משווים מחרוזות בית אחר בית (לפי סדר האלף בית ב-ASCII רגיל). אם שתי המחרוזות מספריות, הן מושוות כמספרים. לסדר שלא תלוי באותיות גדולות וקטנות, או לסדר "טבעי", השתמשו בפונקציות:
אופרטור החללית <=>
$a <=> $b מחזיר -1 כש-$a קטן יותר, 0 כשהם שווים ו-1 כש-$a גדול יותר. הוא פועל לפי אותם כללים כמו < ו-==, וזו הדרך הקצרה ביותר לכתוב callback למיון.
השוואת שני מערכים עם <=> משווה אותם איבר אחר איבר, וכך ה-callback ממיין קודם לפי גיל ואחר כך לפי שם. מתכונים נוספים למיון נמצאים בעמוד מיון מערכים.
טעות נפוצה: השוואת floats עם ==
floats נשמרים בבינארי, ולכן ערכים עשרוניים רבים הם קירובים. 0.1 + 0.2 הוא לא בדיוק 0.3, ו-== רואה את ההפרש.
לכסף, שמרו סנטים שלמים כמספרים שלמים והשוו אותם עם ===.
שאלות נפוצות
מה ההבדל בין == ל-=== ב-PHP?
== ממיר את שני הצדדים לטיפוס משותף ואז משווה, ולכן 1 == "1" הוא true. === מחזיר אמת רק כשהערכים שווים ומאותו טיפוס, ולכן 1 === "1" הוא false. השתמשו ב-=== אלא אם אתם רוצים את ההמרה.
האם 0 == "a" מחזיר true ב-PHP?
לא מאז PHP 8. כשמשווים מספר למחרוזת שאינה מספרית, PHP 8 משווה אותם כמחרוזות, ולכן 0 == "a" הוא false. ב-PHP 7 המחרוזת הומרה ל-0 והתוצאה הייתה true.
מה ההבדל בין != ל-!== ב-PHP?
!= (והכינוי שלו <>) הוא ההפך של ==: הוא false כשהערכים שווים אחרי המרת טיפוסים. !== הוא ההפך של ===: הוא true כשהערכים שונים או שהטיפוסים שלהם שונים, ולכן 0 !== false הוא true בעוד 0 != false הוא false.
איך משווים שני floats ב-PHP?
אל תשתמשו ב-== על תוצאות של חשבון עם floats: 0.1 + 0.2 == 0.3 הוא false. השוו במקום זאת את ההפרש לסבולת קטנה: abs($a - $b) < PHP_FLOAT_EPSILON, או עגלו את שניהם לדיוק שחשוב לכם.