php[world] 2018 - Call for Speakers

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

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

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

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

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

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

<?php

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

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

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

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

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

?>

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

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

Поскольку имена кодировок символов в MySQL не содержат тире/дефис, строка "utf8" применяется в MySQL для установки кодировки UTF-8. Строка "utf-8" неприемлема и потерпит неудачу при установке кодировки символов.

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

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

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

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

echo 
"Информация о новой кодировки:\n";
print_r$mysqli->get_charset() );

?>

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

Примечание: Это работает только с PHP 5.3.6.

<?php
$pdo 
= new PDO("mysql:host=localhost;dbname=world;charset=utf8"'my_user''my_pass');
?>

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

<?php
$conn 
mysql_connect("localhost""my_user""my_pass");
$db   mysql_select_db("world");

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

if (!
mysql_set_charset('utf8'$conn)) {
    echo 
"Ошибка: не удается установить кодировку.\n";
    exit;
}

echo 
'Ваша текущая кодировка: ' .  mysql_client_encoding($conn);
?>
add a note add a note

User Contributed Notes 3 notes

up
1
mkroese at eljakim dot nl
6 months 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
-2
robertoeyzaguirre at hotmail dot com
7 months ago
self::$cont =  new PDO( "mysql:host=".self::$dbHost.";"."dbname=".self::$dbName.";"." charset=utf8", self::$dbUsername, self::$dbUserPassword);
up
-38
go at NOSPAMME dot quidera dot com
5 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