התקנתי PHP 5.2 באחד המחשבים בדיקות שלי היום כמה פיסות של קוד כי בעבר עבד מצוין בגירסה 5.1.6 זרקו שגיאות קטלניות בגרסה החדשה. הודעת השגיאה היה "רמת קינון עמוק מדי - רקורסיבית תלות?"וזה לקח קצת זמן
ב PHP יש שני אופרטורים להשוואה, == ו ===. זה כלל ידוע כי הראשון לא מקפידה על סוג אך השני הוא. כך, for example
הד ( שווא == 0 ); // נכון
הד ( שווא === 0 ); // שקר
- 0 הוא מספר שלם שווא הוא בוליאני
הבעיה שלי נבעה באמצעות הקלדת שאינם מחמירים עם אובייקטים.
$a = new MyObj();
$b = new MyObj();
אם( $a == $b )
…
לא חשבתי מה אני עושה עם הקוד הזה. בהשוואת שני אובייקטים באמצעות אופרטור ההשוואה הלא קפדנית (==) PHP משווה את כל המאפיינים של האובייקטים ואם הם תואמים את האובייקטים הם deemed להיות שווה. אם הם אינם תואמים הם לא שווים. בתוקף, יש לנו השוואה רקורסיבית של כל המאפיינים של כל אובייקט, ואת כל רכושם, וכו '. עד שאנחנו מגיעים בסיסי נתונים מסוגים כמו מחרוזות מספרים שלמים.
If, אולם, אנו משתמשים השוואה קפדנית (===), PHP תבדוק האם שני אובייקטים הם בדיוק אותו חפץ, לא רק חפצים עם אותן התכונות.
בכיתה MyObj
{
הציבור $ p;
}$a = new MyObj();
$b = new MyObj();
$c = new MyObj();
$a->p = 1;
$b->p = 1;
$c->p = 2;
הד ( $a == $c ); // שקר
הד ( $a == $b ); // נכון
הד ( $a === $b ); // שקר
הבעיה מתעוררת אם יש לך הפניות מעגליות חפצים שלך תכונות. כך, for example
בכיתה MyObj
{
הציבור $ p;
}
בכיתה OtherObj
{
הציבור $ q;
}$a = new MyObj();
$b = new OtherObj();
$a->p = $ b;
$b->q = $; // הפניה מעגלית: $a->p->=== Q $$c = new MyObj();
$d = new OtherObj();
$c->p = $ ד;
$d->q = $ c;// התייחסות נוספת עגול: $c->p->ש $ ג ===הד ( $a == $c ); // שגיאה חמורה:
Nesting level too deep – רקורסיבית תלות?
על מנת להשוות $ ל $ ג, PHP חייב להשוות את תכונותיהם. אז ההיגיון PHP הולך משהו כזה: $a == $c if $a->p == $c->p if $a->p->q == $c->p->q if $a->p->q->p == $c->p->q->p וכו '. ללא הגבלת זמן.
PHP 5.1 נראה להחליק את הבעיה איכשהו (כנראה אחרי רמה מסוימת של רקורסיה זה פשוט חזר שווא) – ובדרך כלל זה הסתדר מצוין. PHP 5.2 נכון מייצר שגיאה קטלנית לעיל.
ברגע שאתה יודע את הבעיה, הפתרון הוא קל – השימוש השוואה קפדנית.
הד ( $a === $c ); // שקר (ללא שגיאה)
השוואה קפדנית פשוט לבדוק אם שני עצמים הם באותו מקום בזיכרון ולכן אפילו לא מסתכל על ערכי הנכסים.
נ.ב.. בעיה דומה יכולה להתעורר כאשר באמצעות מפעילי השוואה שלל (להשתמש !== במקום !=) וכאשר באמצעות in_array (הפרמטר השלישי in_array של שימוש כדי לציין השוואה קפדנית).
