Αρχείο για την «Ενότητα’ κατηγορία

PHP Σφάλμα Nesting Επίπεδο πολύ βαθιά Αναδρομική εξάρτηση

12η Μαρτίου, 2010

Έχω εγκαταστήσει την PHP 5.2 σε κάποιον από τους υπολογιστές δοκιμών μου σήμερα και ένα ζευγάρι από τα κομμάτια του κώδικα που εργάστηκε κατά το παρελθόν πρόστιμο στην έκδοση 5.1.6 έριξε μοιραία λάθη στην νέα έκδοση. Το μήνυμα σφάλματος ήταν «καταφύγιο επίπεδο πάρα πολύ βαθιά - recursive εξάρτηση?»Και πήρε λίγο χρόνο

να εντοπίσουμε τη ρίζα του προβλήματος. Εδώ είναι τι είχα κάνει λάθος.

Στην PHP υπάρχουν δύο χειριστές σύγκριση, == Και ===. Είναι γενικά γνωστό ότι η πρώτη δεν είναι αυστηρά όσον αφορά τον τύπο, αλλά το δεύτερο είναι. Έτσι, για παράδειγμα

ηχώ ( ψευδή == 0 ); // αλήθεια

ηχώ ( ψευδή === 0 ); // ψευδής

- 0 είναι ένας ακέραιος και ψευδής είναι μια boolean

Το πρόβλημά μου προέκυψε από τη χρήση μη αυστηρή τυποποίηση με αντικείμενα.

$α = νέα MyObj();
$β = νέα MyObj();
αν( $a == $ b )

Δεν είχε εξετάσει τι έκανα με αυτό τον κωδικό. Κατά τη σύγκριση των δύο αντικείμενα που χρησιμοποιούν τη μη αυστηρή φορέα σύγκριση (==) PHP συγκρίνει όλες τις ιδιότητες των αντικειμένων και αν ταιριάζει με τα αντικείμενα που θεωρούνται ότι είναι ίσο. Αν δεν ταιριάζουν, δεν είναι ίσοι. Στην πραγματικότητα, έχουμε μια αναδρομική σύγκριση όλων των ιδιοτήτων του κάθε αντικειμένου, και όλες τις ιδιότητές τους, κλπ.. μέχρι να φτάσουμε βασικοί τύποι δεδομένων, όπως strings και ακέραιοι.

Αν, ωστόσο, χρησιμοποιούμε αυστηρή σύγκριση (===), PHP θα ελέγξει αν τα δύο αντικείμενα είναι ακριβώς το ίδιο αντικείμενο, δεν είναι μόνο τα αντικείμενα με τις ίδιες ιδιότητες.

τάξη MyObj
{
δημόσια $ p;
}

$α = νέα MyObj();
$β = νέα MyObj();
$γ = νέα MyObj();
$α->p = 1;
$β->p = 1;
$γ->p = 2;
ηχώ ( $a == $ c ); // ψευδής
ηχώ ( $a == $ b ); // αλήθεια
ηχώ ( $ένα === $ b ); // ψευδής

Το πρόβλημα ανακύπτει αν έχετε κυκλικές αναφορές σε αντικείμενα που σας ιδιότητες. Έτσι, για παράδειγμα

τάξη MyObj
{
δημόσια $ p;
}
τάξη OtherObj
{
δημόσια $ q;
}

$α = νέα MyObj();
$β = νέα OtherObj();
$α->p = $ b;
$β->q = $ a; // η κυκλική αναφορά: $α->p->=== Q $ a

$γ = νέα MyObj();
$d = νέα OtherObj();
$γ->p = $ d;
$δ->q = $ c;// μια άλλη κυκλική αναφορά: $γ->p->q $ c ===

ηχώ ( $a == $ c ); // Μοιραίο λάθος:
Ένθεση επίπεδο πάρα πολύ βαθιά – recursive εξάρτηση?

Για να συγκρίνετε $ a και $ c, PHP πρέπει να συγκρίνει τις περιουσίες τους. Έτσι, η λογική στην PHP πάει κάπως έτσι: $a == $ c $ αν α->σ. == $ c->σ. αν η $ a->p->q == $ c->p->q αν η $ a->p->Q->σ. == $ c->p->Q->p κλπ. επ 'αόριστον.

PHP 5.1 φαινόταν να λειάνει πέρα από το πρόβλημα με κάποιο τρόπο (πιθανότατα μετά από ένα ορισμένο επίπεδο αναδρομής απλά επιστρέφει false) – και συνήθως επέλυσε πρόστιμο. PHP 5.2 σωστά παράγει το μοιραίο λάθος παραπάνω.

Μόλις ξέρετε το πρόβλημα, η λύση είναι εύκολη – χρήση αυστηρή σύγκριση.

ηχώ ( $$ a === γ ); // ψευδής (και δεν υπέπεσε σε πλάνη)

Η αυστηρή σύγκριση απλά θα ελέγξει αν τα δύο αντικείμενα που βρίσκονται στην ίδια θέση στη μνήμη και έτσι δεν κάνει ούτε μια ματιά στις τιμές των ακινήτων.

Σημείωση:. Το ίδιο πρόβλημα μπορεί να προκύψει κατά τη χρήση του αναιρείται φορείς σύγκριση (χρήση !== Αντί για !=) και όταν χρησιμοποιούν in_array (τρίτη παράμετρο in_array χρησιμοποιούν για να αναφέρουν αυστηρή σύγκριση).

Μοιραστείτε και απολαύστε

  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency
  • wp socializer sprite mask 16px PHP Error Nesting Level Too Deep Recursive Dependency