PHP 8.1.15 Released!

Zeichensätze

Idealerweise sollte der richtige Zeichensatz auf Serverebene eingestellt werden. Dies wird im Abschnitt » Character Set Configuration des Handbuchs zum MySQL-Server beschrieben. Alternativ dazu bietet jede MySQL-API eine Methode, um den Zeichensatz zur Laufzeit zu setzen.

Achtung

Der Zeichensatz und die Maskierung von Zeichen

Da sich der Zeichensatz auf jede Aktion auswirkt und auch Auswirkungen auf die Sicherheit hat, sollte er bekannt und definiert sein. Zum Beispiel orientiert sich der Mechanismus für das Maskieren (z. B. mysqli_real_escape_string() bei mysqli und PDO::quote() bei PDO_MySQL) an dieser Einstellung. Es ist wichtig zu wissen, dass diese Funktionen nicht den Zeichensatz verwenden, der für eine Abfrage definiert ist, sodass z. B. Folgendes keinen Einfluss auf sie hat:

Beispiel #1 Probleme beim Einstellen des Zeichensatzes mit SQL

<?php

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

// Wirkt sich NICHT auf $mysqli->real_escape_string(); aus
$mysqli->query("SET NAMES utf8mb4");

// Wirkt sich NICHT auf $mysqli->real_escape_string(); aus
$mysqli->query("SET CHARACTER SET utf8mb4");

// Allerdings wirkt sich das auf $mysqli->real_escape_string(); aus
$mysqli->set_charset('utf8mb4');

// Aber das wirkt sich NICHT aus (UTF-8 vs. utf8mb4) - hier keine Bindestriche verwenden
$mysqli->set_charset('UTF-8');
?>

Die folgenden Beispiele zeigen, wie der Zeichensatz mit der jeweiligen API korrekt zur Laufzeit geändert werden kann.

Hinweis: Möglicher Fehler mit UTF-8

Da die Namen von Zeichensätzen in MySQL keine Bindestriche enthalten, muss in MySQL die Zeichenkette "utf8" verwendet werden, um den Zeichensatz auf UTF-8 zu setzen (bis zu 3 Byte UTF-8 Unicode Encoding). Die Zeichenkette "UTF-8" ist dagegen ungültig, weshalb der Zeichensatz mit "UTF-8" nicht geändert werden kann und ein Fehler ausgegeben wird.

Beispiel #2 Beispiel für das Einstellen des Zeichensatzes: mysqli

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

echo
'Der ursprüngliche Zeichensatz: ' . $mysqli->character_set_name() . "\n";

if (!
$mysqli->set_charset('utf8mb4')) {
printf("Fehler beim Laden des Zeichensatzes utf8mb4: %s\n", $mysqli->error);
exit;
}

echo
'Der aktuelle Zeichensatz: ' . $mysqli->character_set_name() . "\n";
?>

Beispiel #3 Beispiel für das Einstellen des Zeichensatzes: 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
5 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
0
legrand dot jeremie at gmail dot com
1 month 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
-48
go at NOSPAMME dot quidera dot com
10 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