htmlentities() vs htmlspecialchars(): la batalla de las funciones PHP

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(): guía detallada con ejemplos

\n\n

¿Alguna vez te has preguntado por qué en PHP hay dos funciones que hacen, aparentemente, lo mismo? htmlentities() y htmlspecialchars() son como dos hermanos gemelos: se parecen por fuera, pero tienen personalidades diferentes. Y elegir entre ellas puede convertirse en una habilidad de superhéroe o en una fuente de dolor de cabeza.

\n\n

Si alguna vez has hecho esta pregunta en Stack Overflow (¡y hay miles!), sabes que la respuesta no siempre es obvia. Hoy vamos a aclarar de una vez por todas para qué sirve cada función, cuándo usar cada una y cómo no meter la pata con las codificaciones.

\n\n

¡Allá vamos!

\n\n

¿Qué hacen realmente estas funciones?

\n\n

Ambas funciones están diseñadas para el escape de caracteres HTML. En palabras simples: convierten caracteres especiales en sus entidades HTML, para que el navegador los muestre como texto y no los interprete como código.

\n\n

Por ejemplo, el carácter < se convierte en &lt;. Esto es críticamente importante para:

\n
    \n
  • Seguridad — protección contra ataques XSS (Cross-Site Scripting)
  • \n
  • Visualización correcta — para que tu texto no «rompa» el marcado HTML
  • \n
\n\n

Pero aquí está el truco: htmlspecialchars() solo trabaja con cuatro caracteres, mientras que htmlentities() lo hace con todas las entidades HTML conocidas.

\n\n

htmlspecialchars(): artillería ligera

\n\n

La función htmlspecialchars() transforma solo estos caracteres:

\n
    \n
  • & (ampersand) → &amp;
  • \n
  • " (comilla doble) → &quot; (si la bandera ENT_NOQUOTES no está establecida)
  • \n
  • ' (comilla simple) → &#039; (si la bandera ENT_QUOTES está establecida)
  • \n
  • < (menor que) → &lt;
  • \n
  • > (mayor que) → &gt;
  • \n
\n\n

Este conjunto es suficiente para el 99% de los casos. ¿Por qué? Porque solo estos caracteres tienen un significado especial en el marcado HTML y pueden romper tu página.

\n\n
<?php\n$user_input = '<script>alert("XSS")</script>';\necho htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');\n// Muestra: &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;\n?>
\n\n

htmlentities(): caballería pesada

\n\n

htmlentities() es ese perfeccionista que convierte en entidades todos los caracteres que tienen un equivalente HTML. Por ejemplo, símbolos de monedas (€, £, ¥), signos matemáticos (∑, ∞, √) e incluso flechas (←, ↑).

\n\n
<?php\n$text = 'Costo: 50€';\necho htmlentities($text, ENT_QUOTES, 'UTF-8');\n// Muestra: Costo: 50&euro;\n?>
\n\n

Suena práctico, ¿verdad? Pero hay un detalle: el rendimiento. htmlentities() es más lenta porque procesa más caracteres. Y si tu sitio maneja miles de líneas, la diferencia se vuelve notable.

\n\n

Diferencia clave: codificación

\n\n

Y aquí llegamos al punto más importante. Ambas funciones aceptan un tercer parámetro: la codificación. Y si no lo especificas, PHP usará el valor de la directiva default_charset en php.ini (normalmente UTF-8).

\n\n

Pero htmlentities() es especialmente sensible a la codificación. Si indicas una codificación incorrecta, la función puede transformar los caracteres de forma incorrecta. Por ejemplo, con ISO-8859-1 algunos caracteres UTF-8 se perderán.

\n\n
<?php\n// Mal ejemplo: codificación no especificada\necho htmlentities('¡Hola, mundo!'); // Puede mostrar una advertencia\n\n// Buen ejemplo: siempre especifica la codificación\necho htmlentities('¡Hola, mundo!', ENT_QUOTES, 'UTF-8');\n?>
\n\n

¿Cuándo usar qué?

\n\n

Blogs

Book Recommendations