MySQL y PHP: UTF-8 con caracteres cirílicos [duplicado]
Estoy intentando insertar un valor cirílico en la tabla MySQL, pero hay un problema con la codificación.
PHP:
<?php
$servername = "localhost";
$username = "a";
$password = "b";
$dbname = "c";
$conn = new mysqli($servername, $username, $password, $dbname);
mysql_query("SET NAMES 'utf8';");
mysql_query("SET CHARACTER SET 'utf8';");
mysql_query("SET SESSION collation_connection = 'utf8_general_ci';");
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "UPDATE `c`.`mainp` SET `search` = 'test тест' WHERE `mainp`.`id` =1;";
if ($conn->query($sql) === TRUE) {
}
$conn->close();
?>
MySQL:
| id | search |
| 1 | test ав |
Nota: el archivo PHP es utf-8
una recopilación de bases de datosutf8_general_ci
Estás mezclando API aquí
mysql_*
ymysqli_*
no las mezclas. Deberías seguirmysqli_
(como parece que lo eres de todos modos), ya quemysql_*
las funciones están obsoletas y eliminadas por completo en PHP7.
Su problema real es un problema de juego de caracteres en alguna parte. A continuación se ofrecen algunos consejos que pueden ayudarle a obtener el juego de caracteres adecuado para su aplicación. Esto cubre la mayoría de los problemas generales que uno puede enfrentar al desarrollar una aplicación PHP/MySQL.
- TODOS los atributos de su aplicación deben estar configurados en UTF-8
- Guarde el documento como UTF-8 sin BOM (si está usando Notepad++, es
Format
->Convert to UTF-8 w/o BOM
) El encabezado tanto en PHP como en HTML debe configurarse en UTF-8
HTML (
<head></head>
etiquetas interiores):<meta charset="UTF-8">
PHP (en la parte superior de su archivo, antes de cualquier salida):
header('Content-Type: text/html; charset=utf-8');
Al conectarse a la base de datos, configure el juego de caracteres en UTF-8 para su objeto de conexión, así (directamente después de conectarse)
mysqli_set_charset($conn, "utf8"); /* Procedural approach */ $conn->set_charset("utf8"); /* Object-oriented approach */
Esto es para
mysqli_*
, hay otros similares paramysql_*
y PDO (ver la parte inferior de esta respuesta).También asegúrese de que su base de datos y tablas estén configuradas en UTF-8, puede hacerlo de esta manera:
ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci; ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
(Los datos ya almacenados no se convertirán al juego de caracteres adecuado, por lo que deberá hacerlo con una base de datos limpia o actualizar los datos después de hacerlo si hay caracteres rotos).
- Si está utilizando
json_encode()
, es posible que deba aplicar laJSON_UNESCAPED_UNICODE
marca; de lo contrario, convertirá los caracteres especiales a su equivalente hexadecimal.
Recuerde que TODO en su proceso de código debe configurarse en UFT-8; de lo contrario, es posible que experimente caracteres rotos en su aplicación.
Además de esta lista, puede haber funciones que tengan un parámetro específico para especificar un juego de caracteres. El manual le informará sobre esto (un ejemplo es htmlspecialchars()
).
También hay funciones especiales para caracteres multibyte, por ejemplo: strtolower()
no reducirá los caracteres multibyte, para eso tendrás que usar mb_strtolower()
, mira esta demostración en vivo .
Nota 1 : Observe que en algún lugar se indica como
utf-8
(con un guión) y en algún lugar comoutf8
(sin él). Es importante que sepas cuándo utilizar cada uno, ya que normalmente no son intercambiables. Por ejemplo, HTML y PHP quierenutf-8
, pero MySQL no.Nota 2 : En MySQL, "juego de caracteres" y "intercalación" no son lo mismo, consulte ¿ Diferencia entre codificación e intercalación? . Sin embargo, ambos deberían configurarse en utf-8; En general, la intercalación debe ser
utf8_general_ci
outf8_unicode_ci
, consulte UTF-8: ¿General? ¿Papelera? Unicódigo? .Nota 3 : Si estás usando emojis, MySQL debe especificarse con un
utf8mb4
juego de caracteres en lugar del estándarutf8
, tanto en la base de datos como en la conexión. HTML y PHP solo tendránUTF-8
.
Configuración de UTF-8 con mysql_
y PDO
PDO: Esto se hace en el DSN de tu objeto. Tenga en cuenta el
charset
atributo,$pdo = new PDO("mysql:host=localhost;dbname=database;charset=utf8", "user", "pass");
mysql_
: Esto se hace de manera muy similar amysqli_*
, pero no toma el objeto de conexión como primer argumento.mysql_set_charset('utf8');
Solución:
mysql_query("SET NAMES 'utf8';");
> $mysqli->set_charset('utf8');