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): boolLa 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 latin1 — no 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 utf8mb4como 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_charsetactualiza 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: utf8mb4Tras 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();
// utf8mb4Manejo 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
utf8mb4almacena caracteres de 4 bytes;utf8los 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
mysqli_connect— abre la conexión que se pasa aset_charset.mysqli_get_charset— obtiene un objeto completo que describe el charset actual (intercalación, comentario, número).mysqli_character_set_name— obtiene solo el nombre del charset activo.mysqli_select_db— cambia la base de datos activa en una conexión existente.
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.