Xevia AccueilBlogActualitésA propos

Supprimer des balises HTML en PHP

C'est en développant ce site que j'ai été confronté à un problème : comment supprimer des balises HTML spécifiques et tout leur contenu ? Attention, il ne s'agit pas de retirer simplement les balises comme le fait la fonction strip_tags() mais bien d'effacer les balises et leur contenu.

J'ai donc développé une petite fonction bien pratique que je dévoile sans plus attendre.

PHP
function removeTags($inputString,$tagArray = array())
{
foreach($tagArray as $tag)
{
$inputString = ereg_replace("</?{$tag}>","+++",$inputString);
$stringArray = explode("+++",$inputString);
foreach($stringArray as $i => $singleString)
{
if($i %2 == 0)
$processedStringArray[] = $singleString;
}
$inputString = implode($processedStringArray);
unset($processedStringArray);
}
return $inputString;
}

Le mieux est d'expliquer par un petit exemple. Imaginons qu'on ait une chaîne HTML "avant le conteneur<p>contenu</p>après le conteneur". On veut supprimer la balise <p> et son contenu.

PHP
$inputString = "avant le conteneur<p>contenu</p>après le conteneur";
$tags = array("p");
 
$outputString = removeTags($inputString,$tags);

removeTags() commence par remplacer toutes les chaînes du style "<p>" ou "</p>" par "+++" au moyen d'une expression régulière. $inputString devient donc "avant le conteneur+++contenu+++après le conteneur". La fonction explode() est ensuite utilisée pour sectionner la chaîne selon les "+++" et ainsi former un tableau de chaînes.

$index $stringArray[$index]
0 "avant le conteneur"
1 "contenu"
2 "après le conteneur"

On parcourt le tableau $stringArray et on en crée un autre, $processedStringArray, en copiant uniquement les chaînes dont l'index est pair. Je rappelle que % est l'opérateur modulo ; $i % 2 donne le reste de la division de $i par 2 donc si ce reste est nul, c'est que $i est pair.

$index $processedStringArray[$index]
0 "avant le conteneur"
1 "après le conteneur"

Enfin, toutes les valeurs de $processedStringArray sont concatenées grâce à implode() ce qui donne à la fin "avant le conteneuraprès le conteneur", exactement ce qu'on recherchait.

Combinée avec strip_tags(), cette fonction peut se révéler bien pratique ... attention tout de même, si deux balises identiques sont imbriquées l'une dans l'autre — par exemple, "<h1><h1>Hello World</h1></h1>" — , la fonction ne se comportera pas normalement et ne supprimera pas tout le contenu de la balise. Heureusement, rares sont les cas où deux balises totalement identiques sont imbriquées. Rien ne nous empêche d'utiliser des expressions régulières comme valeurs dans $tagArray ; on peut alors spécifier des attributs et donc cibler des balises spécifiques, contourner le problème des imbrications de balises qui intervient surtout avec les balises <div>.