un BUG sur preg_replace_callback ?

Petit nouveau ! | 6 Messages

16 oct. 2012, 12:03

Bonjour

Je fréquente le forum depuis des années en tant que simple visiteur. Aujourd'hui, je me suis inscrit pour poster car j'ai trouvé un comportement bien étrange sur la fonction preg_replace_callback :

C'est dans un bout de code qui parse du html pour reformater des div avec des images. D'un point de vue fonctionnel, ce code fonctionne.

Voici le code :

Code : Tout sélectionner

function remplaceDl($matches) { $a = '<div class=\'spip_documents_'.$matches[1].' spip_documents\'><img style=\''.$matches[5].'\' width=\''.$matches[3].'\' height=\''.$matches[4].'\' src=\''.$matches[2].'\'><div class=\'spip_doc_titre\'>'.$matches[6].'</div></div>'; return $a; } $patterns_float = "/<dl class='spip_document_\d* spip_documents spip_documents_(left|right|center).*<dt><img src='(.*)'.*width='(.*)'.*height='(.*)'.*style='(.*)'.*<\/dt>\n<dt.*>(.*)<\/dt>\n<\/dl>/iUms"; $html = preg_replace_callback($patterns_float, 'remplaceDl', $html, -1, $count);
Le symptôme : en sortie du preg_replace_callback, la variable $html est resettée, elle devient vide.
Sous Eclipse PDT, elle passe en status "uninitialized".

Lorsque je débugue en pas à pas, la fonction remplaceDl est bien appelée, avec les bons paramètres, et elle renvoit le résultat attendu. Dans mon exemple, elle est appelée 3 fois. Et $count contient bien la valeur 3 en sortie du preg_replace_callback.

Le bug apparait dans toutes les configurations :
- même si le subject $html passé en paramètre ne contient pas de contenu qui matche avec le pattern,
- le bug se produit sous easyphp et Wamp en local, et aussi sur mon serveur distant.

Apparemment, c'est un truc qui cloche dans $patterns_float.
Si j'y supprime <\/dt> à la fin, celui en gras indiqué ci-dessous :
$patterns_float = "/<dl class='spip_document_\d* spip_documents spip_documents_(left|right|center).*<dt><img src='(.*)'.*width='(.*)'.*height='(.*)'.*style='(.*)'.*<\/dt>\n<dt.*>(.*)<\/dt>\n<\/dl>/iUms";
, cela ne plante pas mais je n'obtiens pas le résultat attendu.

J'ai essayé de diminuer le contenu du subject $html. Et effectivement, si il ne reste que qq dizaines d'octets, cela ne plante plus. Je me demande si cela n'est pas une histoire de pile ?

A noter que j'ai d'autres preg_replace_callback dans la suite du code, qui manipule le même $html, et cela ne plante pas.

Ca vient de quoi d'après vous ?

MERCI pour votre aide. :priere:

Petit nouveau ! | 6 Messages

17 oct. 2012, 17:12

Bonjour

Je crains de ne pas recevoir beaucoup d'aide sur le sujet ; ce que je comprends tant le cas est complexe et particulier.

Pour info, j'ai résolu le problème en faisant le traitement en 2 fois. Un 1er preg_replace_callback pour dégrossir, et un second pour récupérer les pattern restants.

Mais c'est une rustine. Cela m'embête de ne pas comprendre ce qui s'est passé. #-o

Eléphanteau du PHP | 25 Messages

05 nov. 2012, 19:26

Salut,
je sais que ca fait deux semaines deja mais as tu jeté un oeil dans les options de configuration PCRE dans php.ini ?

pcre.backtrack_limit = 100 000 par défaut

Peut être une piste ou alors ca n'a rien à voir avec ton problème :?

Dans le doute ...

Petit nouveau ! | 6 Messages

07 nov. 2012, 01:52

MERCI pour l'aide.

Effectivement, j'avais déjà essayé de titiller ce paramètre en mettant une valeur beaucoup plus élevée. Cela n'a rien donnée.