(modifié le 24 mars 2018 à 23:56)

Il y a une époque où on utilisait toujours la balise courte PHP "<?" mais depuis de nombreux années il est préférable d'utiliser la version longue "<?php".

Après une montée de version du moteur PHP 5.2 vers 7.x sur un vieux site web j'en ai profité pour remplacer toutes les balises courtes par des balises longues. Pour cela j'ai opté pour notepad++ avec une expression régulière pour remplacer le short tag dans tous les fichiers d'un seul coup.

Pourquoi une regex ?

Il n'est pas possible de remplacer purement et simplement une balise pas une autre, déjà parce que j'avais un mélange des 2 et que "<?php" serait remplacé par "<?<?php". Alors oui je pourrais tester la présence du caractère suivant qui est généralement espace mais ce n'était pas toujours le cas dans mon code, et puis parfois c'est un saut de ligne... mais aussi à cause des balises courtes d'ouverture PHP

<?= $variable; ?>

qui équivaut à :

<?php echo $variable; ?>

Enfin si vous utilisez du code XML la balise commence de la même façon "<?xml".

Autant de risques pour foirer votre code, j'ai donc opté pour l'écriture d'une expression régulière.

Avant d'aller plus loin faites une sauvegarde complète de vos fichiers car une erreur de regex est vite arrivée :

Voici la regex

Passer Notepad++ :

  • CTRL + F > onglet "rechercher dans les fichiers d'un dossier"
  • filtre : *.php
  • Dossier : dossier local contenant la racine du site
  • en mode de recherche "expression regulière"
  • Rechercher :

<\?(?!php|xml|=)

  • Remplacer par :

<?php

Pour vous expliquer rapidement cette regex remplace uniquement ce qui contient "<?" et qui n'est pas suivi par "php", "=" ou "xml". C'est à dire que l'on exclut :

  • <?php
  • <?=
  • <?xml

Essayez la regex sur regex101.

Conclusion

Oldschool mais efficace, et si j'en ai eu besoin alors je me suis dit que c'était peut-être aussi votre cas.

Pour ceux qui préfèrent opter pour un remplacement avec sed en console GNU/Linux ça fonctionne aussi :

find /var/www -iname '*.php' -type f | xargs perl -pi -e 's/<\?(?!php|xml|=)/<\?php/g;'

Explication : on cherche récursivement les fichiers *.php  et pour chaque fichier trouvé on remplace la balise courte par la balise longue à l'aide de PERL qui support les regex PCRE.

Alternative avec sed et une référence arrière (merci @pyrou) :

find /var/www -iname '*.php' -type f | xargs sed -i -r 's/(<\?)([^php|xml|=])/<?php\2/gm' ;

Enfn pour vérifier qu'il ne reste rien à remplacer :

find /var/www -iname '*.php' -type f -exec grep -IlP '<\?(?!(php|xml|=))' {} +

Aussi je déconseille (1, 2), ceux qui essayent de penser à tous les cas possibles, c'est le meilleur moyen d'en oublier.

bonus : passer de mysql_* à mysqli_*

Auteur : Mr Xhark

Fondateur du blog et passionné par les nouvelles techno, suivez-moi sur twitter

Tags: ,