htmlentities() vs. htmlspecialchars() : le duel des fonctions d'échappement en PHP
\n\nSi vous avez déjà eu à afficher des données utilisateur sur une page web, vous avez forcément entendu parler des fonctions htmlentities() et htmlspecialchars(). Ce sont les deux outils essentiels de PHP pour se protéger des attaques XSS et afficher correctement les caractères HTML. Mais quelle est la différence entre elles ? Laquelle choisir quand on débute, et laquelle utiliser en production ? On vous explique tout une bonne fois pour toutes.
Imaginez : vous développez un blog en PHP, et un utilisateur poste un commentaire : <script>alert('XSS')</script>. Si vous l'affichez tel quel, le navigateur exécutera le script. Catastrophe ! C'est là que htmlspecialchars() et htmlentities() entrent en jeu. Mais chacune fonctionne à sa manière.
Quel est le point commun entre htmlspecialchars() et htmlentities() ?
\n\nLes deux fonctions convertissent les caractères spéciaux HTML en leurs entités HTML. Par exemple :
\n- \n
&(esperluette) →&\n <(inférieur) →<\n >(supérieur) →>\n "(guillemet double) →"\n '(guillemet simple) →'(ou'selon le drapeau) \n
Sans elles, toute saisie contenant des chevrons ou des esperluettes briserait la mise en page ou ouvrirait la porte aux pirates.
\n\nLa différence principale : l'ampleur de la conversion
\n\nC'est là que réside le secret. htmlspecialchars() est un combattant économique. Elle ne convertit que les cinq caractères fondamentaux qui ont une signification directe en HTML :
- \n
&→&\n <→<\n >→>\n "→"\n '→'(si le drapeauENT_QUOTESest activé) \n
Quant à htmlentities(), c'est une perfectionniste. Elle convertit tous les caractères pour lesquels il existe une entité HTML. Cela inclut non seulement les chevrons, mais aussi les symboles monétaires (€, £, ¥), les signes mathématiques (∑, ∂), les lettres diacritiques (é, ñ, ü) et même les émoticônes (☺).
Exemple simple : la différence en pratique
\n\nRegardons le code. Supposons que nous ayons une chaîne avec du texte français :
\n\n<?php\n$text = "Café & thé <script>alert('test')</script>";\necho "htmlspecialchars : " . htmlspecialchars($text, ENT_QUOTES, 'UTF-8') . "<br>";\necho "htmlentities : " . htmlentities($text, ENT_QUOTES, 'UTF-8');\n?>\n\nRésultat :
\nhtmlspecialchars : Café & thé <script>alert('test')</script>\nhtmlentities : Café & thé <script>alert('test')</script>\n\nDans cet exemple, il n'y a pas de différence, car les caractères "é" et autres lettres latines n'ont pas de signification spéciale en HTML. Mais essayons avec des caractères qui ont des entités :
\n\n<?php\n$text = "€ 100 <b>gras</b>";\necho "htmlspecialchars : " . htmlspecialchars($text, ENT_QUOTES, 'UTF-8') . "<br>";\necho "htmlentities : " . htmlentities($text, ENT_QUOTES, 'UTF-8');\n?>\n\nRésultat :
\nhtmlspecialchars : € 100 <b>gras</b>\nhtmlentities : € 100 <b>gras</b>\n\nVous voyez ? htmlentities() a transformé le symbole euro "€" en son entité €. Alors que htmlspecialchars() l'a laissé tel quel. Pourquoi ? Parce que "€" n'est pas un caractère dangereux pour le HTML — le navigateur l'affichera correctement même sans échappement.
Quand utiliser htmlspecialchars() ?
\n\nC'est votre choix par défaut. Utilisez htmlspecialchars() dans 99% des cas lorsque vous affichez des données utilisateur