pcre.backtrack_limit

Σε ένα από τα project που δουλεύω, έχω φτιάξει ένα μικρό parser για τα templates. Ουσιαστικά έχει διάφορα conditions (π.χ. ISHOME αν είναι η αρχική σελίδα, REGISTERED αν ο χρήστης έχει κάνει login κλπ). Αυτά τρέχουν με regular expressions απλά και γρήγορα.

Όλα δούλευαν ρολόι, μέχρι που σε κάποιο template ένα από τα regular expression σταμάτησε να δουλεύει, χωρίς όμως κάποιο notice, warning ή error. Μάλιστα αυτό γίνονταν μόνο στο laptop μου και όχι στον desktop υπολογιστή.

Μετά από λίγο σκάλισμα, αποφάσισα να τρέξω την preg_last_error() ώστε να δω αν υπάρχει κάποιο λάθος που για κάποιο λόγο δεν εμφανίζεται στα warnings της php. Και είχα δίκιο, η εντολή μου επέστρεφε την τιμή 2 που ισούται με το PREG_BACKTRACK_LIMIT_ERROR, κάτι που δεν μου είχε ξανατύχει.

Ψάχνοντας λίγο ακόμα, βρήκα την ρύθμιση pcre.backtrack_limit που υπάρχει από την PHP 5.2, και στις τελευταίες εκδόσεις η προεπιλογή είναι 1000000, αλλά πριν την 5.3.7 ήταν το ένα δέκατο (100000).

Στο συγκεκριμένο template που έτρεχα, είχα ένα πολύ μεγάλο κομμάτι html κώδικα μέσα σε ένα tag [ISHOME][/ISHOME]. Επειδή ήταν πολύ μεγάλο, αυτό το συγκεκριμένο όριο χτυπούσε και σταματούσε την εκτέλεση του regular expression, χωρίς όμως να χτυπάει ο υπόλοιπος κώδικας. Και ο λόγος που γίνονταν μόνο στο laptop είναι ότι έτρεχα πιο παλιά έκδοση της php.

Η λύση βέβαια ήταν κάτι τόσο απλό:

ini_set('pcre.backtrack_limit', '1000000');

και για να έχω και τη συνείδηση μου ήσυχη, το έκανα τελικά κάπως έτσι:

$backtrack_limit = ini_get('pcre.backtrack_limit');
 if ($backtrack_limit < 1000000){
 ini_set('pcre.backtrack_limit', '1000000'); 
 }
// εδώ μπήκε ο κώδικας με τα regular expressions
ini_set('pcre.backtrack_limit', $backtrack_limit);

Αν ποτέ αντιμετωπίσετε κάτι ανάλογο, αυτή είναι μια λύση.