in_array($needle, $haystack) מחזירה true אם הערך נמצא איפשהו במערך ו-false אם לא. העבירו true כארגומנט השלישי, in_array($needle, $haystack, true), כדי לדרוש גם אותו טיפוס; בצורה המחמירה הזו כדאי להשתמש כברירת מחדל.
in_array() מסתכלת רק על ערכים. כדי לבדוק אם מפתח קיים, השתמשו ב-array_key_exists() או ב-isset().
הפרמטר המחמיר
בלי הארגומנט השלישי, in_array() משווה עם ==, שממיר טיפוסים לפני ההשוואה. עם true, היא משווה עם ===: גם הערך וגם הטיפוס חייבים להתאים. ההבדל מופיע ברגע שהמערך מערבב מספרים ומחרוזות, וזה נפוץ בנתונים מטפסים, מכתובות URL ומקובצי CSV.
כל תא בטבלה הוא מה ש-== ו-=== מחזירים לזוג הערכים הזה ב-PHP 8.3. in_array() עונה true אם המחט ואיבר כלשהו נותנים true בטבלה במצב שבו אתם משתמשים. עברו בין הלשוניות והסתכלו על השורות של null, true ומחרוזות מספריות.
| $a == $b | true | false | null | 0 | 1 | "0" | "1" | "" | "abc" | "10" | "1e1" | 10 | [] |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| true | |||||||||||||
| false | |||||||||||||
| null | |||||||||||||
| 0 | |||||||||||||
| 1 | |||||||||||||
| "0" | |||||||||||||
| "1" | |||||||||||||
| "" | |||||||||||||
| "abc" | |||||||||||||
| "10" | |||||||||||||
| "1e1" | |||||||||||||
| 10 | |||||||||||||
| [] |
כלל אחד השתנה ב-PHP 8: מחרוזת לא מספרית כבר לא שווה ל-0, ולכן in_array('abc', [0]) הוא false היום אבל היה true ב-PHP 7. קוד שנכתב ל-PHP 7 הסתמך על זה לפעמים, וזו עוד סיבה להעביר true ולא להיות תלויים בכללי ההמרה. עמוד אופרטורי ההשוואה מסביר אותם במלואם.
in_array בלי תלות באותיות גדולות וקטנות
in_array() משווה מחרוזות בדיוק, ולכן 'PHP' ו-'php' שונים. המירו גם את המחט וגם את המערך לאותיות קטנות לפני הבדיקה. mb_strtolower() מטפלת גם באותיות עם סימנים דיאקריטיים ובאותיות שאינן לטיניות.
בדיקת כמה ערכים בבת אחת
in_array() מקבלת מחט אחת. לכמה מחטים, השוו את המערכים כקבוצות: array_diff() מחזירה את המחטים שחסרות, כך שתוצאה ריקה אומרת שכולן קיימות, ו-array_intersect() מחזירה את המחטים שנמצאו.
array_diff() ו-array_intersect() משוות ערכים כמחרוזות, ולכן 1 ו-'1' נחשבים שם שווים.
in_array על מערך רב ממדי
in_array() לא מחפשת בתוך מערכים מקוננים. כדי לבדוק אם לשורה כלשהי יש שדה עם ערך מסוים, חלצו קודם את השדה הזה עם array_column(), ואז חפשו ברשימה השטוחה.
השורה האחרונה מראה שהמחט יכולה להיות בעצמה מערך: היא מתאימה לשורה זהה, עם אותם מפתחות, ערכים וסדר.
in_array מול array_search מול isset
שלושתן עונות על "האם זה שם?", אבל הן מחזירות דברים שונים ורצות במהירויות שונות:
| קריאה | מחזירה | מהירות על מערך גדול |
|---|---|---|
in_array($v, $arr, true) | true או false | סורקת כל איבר |
array_search($v, $arr, true) | את המפתח, או false | סורקת כל איבר |
isset($set[$v]) | true או false | חיפוש hash אחד |
השתמשו ב-array_search() כשאתם צריכים לדעת איפה הערך נמצא. כשאתם בודקים הרבה ערכים מול אותה רשימה גדולה, הפכו את הרשימה פעם אחת כך שהערכים שלה יהפכו למפתחות, והשתמשו ב-isset().
הזמנים משתנים מהרצה להרצה, אבל הפער לא: החיפוש עם isset() נשאר קבוע בעוד in_array() גדלה עם גודל הרשימה. array_flip() עובדת רק עם ערכי מחרוזת ומספר שלם, וכפילויות מתמזגות למפתח אחד, וזה לא משנה לבדיקת חברות.
שאלות נפוצות
מה עושה הפרמטר השלישי של in_array?
הוא מפעיל השוואה מחמירה. in_array($x, $arr, true) משווה עם ===, ולכן גם הטיפוס חייב להתאים ולא רק הערך: in_array('1', [1, 2], true) הוא false. בלעדיו, PHP משווה עם == וממירה טיפוסים קודם.
האם תמיד להשתמש במצב מחמיר עם in_array?
בדרך כלל כן. מצב רופף גורם ל-in_array(null, [0]), ל-in_array(true, ['any string']) ול-in_array('1e1', ['10']) להחזיר כולם true. השאירו אותו כבוי רק כשאתם רוצים בכוונה ש-'5' מטופס יתאים למספר השלם 5.
איך הופכים את in_array ללא רגישה לאותיות גדולות וקטנות?
המירו את שני הצדדים לאותיות קטנות: in_array(strtolower($needle), array_map('strtolower', $haystack), true). השתמשו ב-mb_strtolower כשהטקסט יכול להכיל אותיות שאינן ASCII.
איך בודקים אם כמה ערכים נמצאים במערך?
כדי לדרוש את כולם, בדקו ששום דבר לא נשאר: !array_diff($needles, $haystack). כדי לדרוש לפחות אחד, בדקו שיש חפיפה: (bool) array_intersect($needles, $haystack).
האם in_array איטית?
היא סורקת את המערך איבר אחר איבר, ולכן היא איטית במערכים גדולים שנבדקים פעמים רבות. הפכו את המערך פעם אחת עם $set = array_flip($haystack); והשתמשו ב-isset($set[$value]), שהוא חיפוש יחיד בטבלת hash.