W3docs

Guía completa sobre la función mysqli_set_charset en PHP

Aprende a usar mysqli_set_charset en PHP para alinear el juego de caracteres de tu script con la conexión MySQL y evitar errores de codificación.

Cuando almacenas nombres, comentarios o emoji en MySQL, los bytes solo se transmiten correctamente si PHP y la base de datos acuerdan un juego de caracteres — la correspondencia entre bytes y caracteres. La función mysqli_set_charset establece el juego de caracteres para la conexión entre tu script PHP y el servidor MySQL, de modo que todo lo que envíes y recibas se interprete de la misma manera en ambos lados.

Esta página explica qué hace la función, por qué establecer el charset en la conexión es importante (y por qué también es una medida de seguridad), y cómo usarla tanto con la API procedural como con la orientada a objetos de mysqli.

Qué hace mysqli_set_charset

mysqli_set_charset le indica al servidor MySQL qué juego de caracteres usará el cliente (tu script PHP) durante el resto de la conexión. Afecta cómo se interpretan las cadenas de consulta, cómo se codifican los resultados al regresar y qué bytes trata mysqli_real_escape_string() como especiales.

La firma procedural recibe primero la conexión y luego el nombre del charset, y devuelve true en caso de éxito o false en caso de error:

mysqli_set_charset(mysqli $connection, string $charset): bool

La forma orientada a objetos es un método del objeto de conexión:

$connection->set_charset($charset);

El argumento $charset es un nombre de juego de caracteres de MySQL como utf8mb4, utf8 o latin1no un nombre de codificación de PHP. Usa utf8mb4 para soporte Unicode completo, incluidos caracteres de 4 bytes como los emoji; el alias más antiguo utf8 en MySQL solo almacena hasta 3 bytes por carácter y no puede contener emoji.

Establécelo en la conexión, no solo en las consultas. Ejecutar SET NAMES utf8mb4 como consulta cambia el charset del lado del servidor pero no actualiza el valor que usa la biblioteca del cliente C para el escapado. mysqli_set_charset actualiza ambos, por eso es la forma correcta y segura de cambiar el charset.

Conectar y establecer el charset

mysqli_set_charset necesita una conexión existente, así que primero abre una con mysqli_connect. El ejemplo siguiente se conecta y luego establece inmediatamente utf8mb4:

<?php

$host     = 'localhost';
$user     = 'username';
$password = 'password';
$database = 'mydatabase';

$connection = mysqli_connect($host, $user, $password, $database);

if (!$connection) {
    die('Connection failed: ' . mysqli_connect_error());
}

if (!mysqli_set_charset($connection, 'utf8mb4')) {
    die('Error setting charset: ' . mysqli_error($connection));
}

echo 'Current charset: ' . mysqli_character_set_name($connection);
// Current charset: utf8mb4

Tras la llamada exitosa, mysqli_character_set_name informa el charset activo, confirmando que el cambio surtió efecto.

Ejemplo orientado a objetos

Si usas la API orientada a objetos de mysqli, llama a set_charset() como método. Es una buena práctica hacerlo justo después de construir la conexión, antes de ejecutar cualquier consulta:

<?php

$mysqli = new mysqli('localhost', 'username', 'password', 'mydatabase');

if ($mysqli->connect_errno) {
    die('Connection failed: ' . $mysqli->connect_error);
}

if (!$mysqli->set_charset('utf8mb4')) {
    die('Error setting charset: ' . $mysqli->error);
}

echo $mysqli->character_set_name();
// utf8mb4

Manejo de errores

mysqli_set_charset devuelve false si el servidor no admite el charset solicitado (por ejemplo, un error tipográfico como utf8mb44). Comprueba siempre el valor de retorno en lugar de asumir el éxito:

<?php

if (!mysqli_set_charset($connection, 'utf8mb4')) {
    // Log it and stop — running queries with the wrong charset
    // can corrupt stored text and weaken escaping.
    throw new RuntimeException(
        'Failed to set charset: ' . mysqli_error($connection)
    );
}

Puedes llamar a la función más de una vez en la misma conexión para cambiar el charset a mitad de sesión, aunque en la práctica se establece una vez justo después de conectar y se deja así.

Por qué es importante

  • Texto correcto. Sin un charset coincidente, las letras acentuadas y los scripts no latinos regresan como ? o mojibake (caracteres ilegibles como é en lugar de é).
  • Emoji y Unicode completo. Solo utf8mb4 almacena caracteres de 4 bytes; utf8 los elimina o trunca silenciosamente.
  • Seguridad. mysqli_real_escape_string() escapa basándose en el charset de la conexión. Establecerlo correctamente cierra una clase de vectores de inyección SQL que explotan desajustes multibyte. Aun así, prefiere las sentencias preparadas sobre el escapado manual.

Funciones relacionadas

Conclusión

mysqli_set_charset alinea el juego de caracteres de tu script PHP con tu conexión MySQL, garantizando que el texto se transmita correctamente y que el escapado funcione de forma segura. Establécelo en utf8mb4 justo después de conectar, comprueba su valor de retorno y habrás cubierto los casos más comunes — desde nombres acentuados hasta emoji.

Práctica

Práctica
¿Cuál llamada establece correctamente el juego de caracteres de la conexión a Unicode completo y es la opción recomendada?
¿Cuál llamada establece correctamente el juego de caracteres de la conexión a Unicode completo y es la opción recomendada?
Was this page helpful?