htmlentities() vs. htmlspecialchars(): a batalha dos titãs da escapagem em PHP
\n\nSe você já precisou exibir dados de usuários em uma página web, com certeza já ouviu falar das funções htmlentities() e htmlspecialchars(). Elas são as duas principais ferramentas do PHP para proteção contra ataques XSS e para exibir corretamente caracteres HTML. Mas qual é a diferença entre elas? Qual escolher como iniciante, e qual usar como profissional? Vamos entender de uma vez por todas.
Imagine: você está criando um blog em PHP, e um usuário insere um comentário: <script>alert('XSS')</script>. Se você simplesmente exibir isso na tela, o navegador executará o script. Um desastre! É aí que entram htmlspecialchars() e htmlentities(). Mas cada uma funciona de um jeito.
O que htmlspecialchars() e htmlentities() têm em comum?
\n\nAmbas as funções convertem caracteres especiais do HTML em suas entidades HTML (entities). Por exemplo:
\n- \n
&(e comercial) →&\n <(menor que) →<\n >(maior que) →>\n "(aspas duplas) →"\n '(aspas simples) →'(ou'dependendo da flag) \n
Sem elas, qualquer entrada com colchetes angulares ou e comercial quebraria o layout ou abriria portas para hackers.
\n\nA principal diferença: a escala da conversão
\n\nAqui está o segredo. htmlspecialchars() é um guerreiro econômico. Ele converte apenas os cinco caracteres principais que têm significado direto em HTML:
- \n
&→&\n <→<\n >→>\n "→"\n '→'(se a flagENT_QUOTESestiver ativada) \n
Já htmlentities() é um perfeccionista. Ele converte todos os caracteres para os quais existem entidades HTML. Isso inclui não apenas colchetes angulares, mas também símbolos de moedas (€, £, ¥), sinais matemáticos (∑, ∂), letras com acentos (é, ñ, ü) e até emojis (☺).
Exemplo simples: a diferença na prática
\n\nVamos ver o código. Suponha que temos uma string com texto em francês:
\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\nResultado:
\nhtmlspecialchars: Café & thé <script>alert('test')</script>\nhtmlentities: Café & thé <script>alert('test')</script>\n\nNeste exemplo, não há diferença, porque os caracteres "é" e outras letras latinas não têm significado especial em HTML. Mas vamos testar com caracteres que possuem entidades:
\n\n<?php\n$text = "€ 100 <b>bold</b>";\necho "htmlspecialchars: " . htmlspecialchars($text, ENT_QUOTES, 'UTF-8') . "<br>";\necho "htmlentities: " . htmlentities($text, ENT_QUOTES, 'UTF-8');\n?>\n\nResultado:
\nhtmlspecialchars: € 100 <b>bold</b>\nhtmlentities: € 100 <b>bold</b>\n\nPercebeu? htmlentities() transformou o símbolo do euro "€" em sua entidade €. Já htmlspecialchars() o manteve como está. Por quê? Porque "€" não é um caractere perigoso para HTML — o navegador o exibirá corretamente mesmo sem escapagem.
Quando usar htmlspecialchars()?
\n\nEsta é sua escolha padrão. Use htmlspecialchars() em 99% dos casos ao exibir dados do usuário.