htmlentities() vs htmlspecialchars() en PHP: guía completa con ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

htmlentities() vs. htmlspecialchars(): la batalla del escape en PHP

\n\n

Si alguna vez has tenido que mostrar datos de usuarios en una página web, seguro que has oído hablar de las funciones htmlentities() y htmlspecialchars(). Son las dos herramientas principales de PHP para protegerte de ataques XSS y mostrar correctamente los caracteres HTML. Pero, ¿cuál es la diferencia entre ellas? ¿Cuál debería usar un principiante y cuál un experto? Vamos a aclararlo de una vez por todas.

\n\n

Imagina que estás creando un blog en PHP y un usuario escribe un comentario como este: <script>alert('XSS')</script>. Si lo muestras directamente en pantalla, el navegador ejecutará el script. ¡Un desastre! Aquí es donde entran en juego htmlspecialchars() y htmlentities(). Pero cada una funciona de manera diferente.

\n\n

¿Qué tienen en común htmlspecialchars() y htmlentities()?

\n\n

Ambas funciones convierten caracteres especiales HTML en sus entidades HTML correspondientes. Por ejemplo:

\n
    \n
  • & (ampersand) → &amp;
  • \n
  • < (menor que) → &lt;
  • \n
  • > (mayor que) → &gt;
  • \n
  • " (comilla doble) → &quot;
  • \n
  • ' (comilla simple) → &#039; (o &apos; según la bandera)
  • \n
\n\n

Sin ellas, cualquier entrada con corchetes angulares o ampersands rompería el diseño o abriría la puerta a los hackers.

\n\n

La diferencia clave: el alcance de la conversión

\n\n

Aquí está el secreto. htmlspecialchars() es un luchador eficiente. Solo convierte los cinco caracteres principales que tienen un significado directo en HTML:

\n
    \n
  • & → &amp;
  • \n
  • < → &lt;
  • \n
  • > → &gt;
  • \n
  • " → &quot;
  • \n
  • ' → &#039; (si se incluye la bandera ENT_QUOTES)
  • \n
\n\n

En cambio, htmlentities() es un perfeccionista. Convierte todos los caracteres para los que existen entidades HTML. Esto incluye no solo los corchetes angulares, sino también símbolos de moneda (€, £, ¥), signos matemáticos (∑, ∂), letras con acentos (é, ñ, ü) e incluso emojis (☺).

\n\n

Ejemplo práctico: la diferencia en acción

\n\n

Veamos el código. Supongamos que tenemos una cadena con texto en 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\n

Resultado:

\n
htmlspecialchars: Café & thé <script>alert('test')</script>\nhtmlentities: Café & thé <script>alert('test')</script>
\n\n

En este ejemplo no hay diferencia, porque los caracteres "é" y otras letras latinas no tienen un significado especial en HTML. Pero probemos con caracteres que sí tienen entidades:

\n\n
<?php\n$text = "€ 100 <b>negrita</b>";\necho "htmlspecialchars: " . htmlspecialchars($text, ENT_QUOTES, 'UTF-8') . "<br>";\necho "htmlentities: " . htmlentities($text, ENT_QUOTES, 'UTF-8');\n?>
\n\n

Resultado:

\n
htmlspecialchars: € 100 <b>negrita</b>\nhtmlentities: &euro; 100 <b>negrita</b>
\n\n

¿Lo ves? htmlentities() convirtió el símbolo del euro "€" en su entidad &euro;. Mientras que htmlspecialchars() lo dejó tal cual. ¿Por qué? Porque "€" no es un carácter peligroso para HTML: el navegador lo muestra correctamente sin necesidad de escaparlo.

\n\n

¿Cuándo usar htmlspecialchars()?

\n\n

Es tu opción por defecto. Usa htmlspecialchars() en el 99% de los casos cuando muestres datos de usuarios en pantalla. Es más rápida, más ligera y cubre todos los caracteres que realmente representan un riesgo de seguridad. Para la mayoría de aplicaciones web, es todo lo que necesitas.

Blogs

Book Recommendations