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 :
Quand tu te plantes dans une regex en mode "remplacer tout" dans Notepad++ (ou via sed)... bien content d'avoir des snapshots d'1 heure en arrière chez @yulPa_io y'a plus qu'à patienter 🙂 pic.twitter.com/imUsD1NZTw
— xɦΛƦҠ (@xhark) March 18, 2018
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
3 commentaires
Hello,
Une proposition : on commence par <?
puis on a soit
- la fin de ligne
- ni x ni p ni =
- x mais pas suivi de m
- xm mais pas suivi de l
- p mais pas suivi de h
- ph mais pas suivi de p
avec les protections des caractères, j'obtiens
sed -e 's/<?\($\|[^xp=]\|x[^m]\|xm[^l]\|p[^h]\|ph[^p]\)/<?php\1/g'
Y'en a un qui code sans utiliser git 😉 !!
@GrandKoala: as-tu testé ta regex sur regex101 ? je ne comprends pas la présence de "$". Entre-temps j'ai ajouté une regex sed POSIX pour info