PHP 8.4.1 Released!

Кодировки символов

В идеальном случае кодировка символов должна устанавливаться на уровне сервера и делать это согласно описанию в разделе » Конфигурация кодировки символов документации сервера MySQL. В качестве альтернативы каждый MySQL API предлагает метод для установки кодировки символов во время выполнения.

Предостережение

Кодировка символов и экранирование символов

Кодировка символов должна быть чётко определена, поскольку влияет на каждое действие, в том числе на действия с последствиями для безопасности. Например, механизмы экранирования (такие как mysqli_real_escape_string() для mysqli и PDO::quote() для PDO_MySQL) зависят от этих настроек. Важно понимать, что эти функции не используют кодировку символов определённую в запросе, так например, следующие запросы не будут влиять на поведение этих функций:

Пример #1 Проблемы установки кодировки символов с помощью SQL

<?php

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

// Этот запрос не влияет на поведение $mysqli->real_escape_string();
$mysqli->query("SET NAMES utf8mb4");

// И этот не влияет на $mysqli->real_escape_string();
$mysqli->query("SET CHARACTER SET utf8mb4");

// но вот этот запрос повлияет на поведение $mysqli->real_escape_string();
$mysqli->set_charset('utf8mb4');

// а этот НЕ повлияет, потому что нельзя использовать "-"
$mysqli->set_charset('UTF-8'); // (utf8mb4, а не UTF-8)
?>

Примеры ниже демонстрируют, как правильно изменять кодировку символов во время выполнения, используя каждый из API.

Замечание: Возможная путаница с UTF-8

Поскольку имена кодировок символов в MySQL не содержат тире/дефис, строка "utf8" применяется в MySQL для установки кодировки UTF-8 (до 3 байт в кодировке Unicode UTF-8). Строка "UTF-8" неприемлема и выбросит ошибку при установке кодировки символов.

Пример #2 Пример установки кодировки символов: mysqli

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

echo
'Первоначальная кодировка: ' . $mysqli->character_set_name() . "\n";

if (!
$mysqli->set_charset('utf8mb4')) {
printf("Ошибка загрузки кодировки utf8mb4: %s\n", $mysqli->error);
exit;
}

echo
'Ваша текущая кодировка: ' . $mysqli->character_set_name() . "\n";
?>

Пример #3 Пример установки кодировки символов: pdo_mysql

<?php
$pdo
= new PDO("mysql:host=localhost;dbname=world;charset=utf8mb4", 'my_user', 'my_pass');
?>
Добавить

Примечания пользователей 2 notes

up
22
mkroese at eljakim dot nl
7 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');
To Top