PHPerKaigi 2024

Conjuntos de caracteres

Idealmente, um conjunto de caracteres adequado será definido no nível do servidor, e isso é descrito na seção » Configuração do conjunto de caracteres do manual do servidor MySQL. Alternativamente, cada API MySQL oferece um método para definir o conjunto de caracteres em tempo de execução.

Cuidado

O conjunto de caracteres e escape de caracteres

O conjunto de caracteres deve ser entendido e definido, pois afeta todas as ações e inclui implicações de segurança. Por exemplo, o mecanismo de escape (por exemplo, mysqli_real_escape_string() para mysqli e PDO::quote() para PDO_MySQL) irá aderir a esta configuração. É importante perceber que essas funções não usarão o conjunto de caracteres definido com uma consulta, portanto, por exemplo, o seguinte não terá efeito sobre elas:

Exemplo #1 Problemas ao definir o conjunto de caracteres com SQL

<?php

$mysqli
= new mysqli("localhost", "my_user", "my_password", "world");

// Não afetará $mysqli->real_escape_string();
$mysqli->query("SET NAMES utf8mb4");

// Não afetará $mysqli->real_escape_string();
$mysqli->query("SET CHARACTER SET utf8mb4");

// Mas isto afetará $mysqli->real_escape_string();
$mysqli->set_charset('utf8mb4');

// Porém, isto NÃO irá afetá-la (UTF-8 vs utf8mb4) -- não use hífens aqui
$mysqli->set_charset('UTF-8');
?>

Abaixo estão exemplos que demonstram como alterar adequadamente o conjunto de caracteres em tempo de execução usando cada API.

Nota: Possível confusão UTF-8

Como os nomes dos conjuntos de caracteres no MySQL não contêm hífens, a string "utf8" é válida no MySQL para definir o conjunto de caracteres como UTF-8 (codificação Unicode UTF-8 de até 3 bytes). A string "UTF-8" não é válida, pois o uso de "UTF-8" não alterará o conjunto de caracteres e gerará um erro.

Exemplo #2 Exemplo de definição do conjunto de caracteres: mysqli

<?php
$mysqli
= new mysqli("localhost", "my_user", "my_password", "world");

echo
'Conjunto de caracteres inicial: ' . $mysqli->character_set_name() . "\n";

if (!
$mysqli->set_charset('utf8mb4')) {
printf("Erro ao carregar o conjunto de caracteres utf8mb4: %s\n", $mysqli->error);
exit;
}

echo
'Seu conjunto de caracteres atual é: ' . $mysqli->character_set_name() . "\n";
?>

Exemplo #3 Exemplo de definição do conjunto de caracteres: pdo_mysql

<?php
$pdo
= new PDO("mysql:host=localhost;dbname=world;charset=utf8mb4", 'my_user', 'my_pass');
?>
add a note

User Contributed Notes 3 notes

up
21
mkroese at eljakim dot nl
6 years ago
Please note that MySQL's utf8 encoding has a maximum of 3 bytes and is unable to encode *all* unicode characters.

If you need to encode characters beyond the BMP (Basic Multilingual Plane), like emoji or other special characters, you will need to use a different encoding like utf8mb4 or any other encoding supporting the higher planes. Mysql will discard any characters encoded in 4 bytes (or more).

See https://dev.mysql.com/doc/refman/5.7/en/charset-unicode-utf8mb4.html for more information on the matter
up
-1
legrand dot jeremie at gmail dot com
1 year ago
After setting the charset, you should define the 'collation' too, to give information on how sorting results on requests. By default, it is 'utf8mb4_general_ci', which is a simplified set of sorting rules. For the official rules, edicted by Unicode, it should be 'utf8mb4_unicode_ci'.

For example:
\mysqli_set_charset($hdl, 'utf8mb4');
\mysqli_query($hdl, 'SET collation_connection = utf8mb4_unicode_520_ci');
up
-49
go at NOSPAMME dot quidera dot com
11 years ago
If none of the character set alterations work and the data is valid UTF8 and is garbled when saved in mysql. Then your table is not supporting UTF8 and likely is Latin1 or something else. So you will need to update you table, in the case of MySQL do the following:

ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8;
To Top