FluxBB.fr

Le site des utilisateurs francophones de FluxBB.

Recherche rapide

Caractères UTF-8 composés de quatre octets

Le jeu de caractères actuellement nommé utf8 utilise un maximum de trois octets par caractère et ne contient que des caractères BMP : Basic Multilingual Plane, c'est-à-dire les 65534 premiers codes (0x0000 à 0xFFFD) du standard UCS (ISO 10646) qui définit le Universal Character Set (UCS).

UCS contient tous les caractères de tous les autres jeux de caractères standards. Il garantit également une compatibilité circulaire, ce qui signifie que les tables de conversions permettent de ne perdre aucune information quand une chaîne de caractères est convertie dans un autre codage, puis reconvertie en sens inverse.

UCS contient les caractères nécessaires pour représenter presque tous les langages connus. En plus des langues utilisant une extension de l'alphabet latin, il inclut : Grec, Cyrillique, Hébreu, Arabe, Arménien, Grégorien, Japonais, Chinois, Hiragana, Katakana, Coréen, Hangul, Devangari, Bengali, Gurmukhi, Gujarati, Oriya, Tamil, Telugu, Kannada, Malayam, Thai, Lao, Bopomofo, et d'autres encore. Depuis MySQL 5.5.3 sont supporté les extensions Unicode aux caractères BMP : les caractères utf8 composés de quatre octets, c'est-à-dire les codes du standard UCS (ISO 10646) supérieurs à 65534 (> 0xFFFF) et ce support se nomme utf8mb4. Par exemple, Voir ici

  • l'ensemble utf8mb4 utilise un maximum de quatre octets par caractère et supporte les caractères complémentaires, par exemple ceux de Unicode version 6, pour peu qu'une police de caractère (Fonte) dispose des glyphes associés.
  • l'ensemble utf8mb3 est un alias de utf8 et permet de différentier plus visiblement le codage à trois octets de celui à quatre octets.

Néanmoins, pour les commandes telles que SHOW, CREATE TABLE or SELECT l'alias utf8mb3 est systématiquement convertit en utf8.

Pour un caractère BMP, utf8 et utf8mb4 fonctionnent de manière identique : même code, même encodage, même longueur (Nombre d'octets), même façon d'enregistrer dans la base de données.

Pour les caractères supplémentaires, par exemple Unicode version 6, utf8 ne peut pas stocker le caractère et générera une erreur car utf8mb4 nécessite quatre octets. Donc, si on veut supporter les caractères uft8 à quatre octets, il est impératif de le déclarer explicitement pour les bases, tables et colonnes le nécessitant.

Si une table avait été précédemment créée pour supporter utf8, par exemple :

CREATE TABLE t1 (
  col1 CHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  col2 CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
) CHARACTER SET utf8;

La requête suivante permettra, sans aucune perte de données, de transcoder la table pour qu'elle accepte les caractères utf8 à quatre octets :(Il est indispensable de préciser le nom des colonnes à transcoder)

ALTER TABLE t1
  DEFAULT CHARACTER SET utf8mb4,
  MODIFY col1 CHAR(10)
    CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  MODIFY col2 CHAR(10)
    CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;

Plus simplement, on peut utiliser :

ALTER TABLE t1
  CONVERT TO CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci (ou utf8mb4_bin);

Sans être obligé de donner les noms des colonnes ; seules les colonnes nécessitant d'être transcodées le seront automatiquement.

Pour que MySQL accepte les requêtes contenant des données avec des caractères utf8 à quatre octets, il est impératif de la déclarer explicitement, donc d'envoyer la commande :

SET NAMES utf8mb4;

au lieu de

SET NAMES utf8;

avant les requêtes.

Modification de PhpMyAdmin

Note : À partir de la version 3.5.0 PhpMyAdmin peut supporter les caractères utf8 à quatre octets sans devoir être modifié.

Pour que PhpMyAdmin accepte, lui aussi, les caractères utf8 à quatre octets il faut :

  • Utiliser une version MySQL supérieure à 5.5.3
  • Modifier le fichier phpmyadmin/libraries/database_interface.lib.php

Remplacer :

    // Skip charsets for Drizzle
    if (!PMA_DRIZZLE) {
        if (! empty($GLOBALS['collation_connection'])) {
            PMA_DBI_query("SET CHARACTER SET 'utf8';", $link, PMA_DBI_QUERY_STORE);
            PMA_DBI_query("SET collation_connection = '" . PMA_sqlAddslashes($GLOBALS['collation_connection']) . "';", $link, PMA_DBI_QUERY_STORE);
        } else {
            PMA_DBI_query("SET NAMES 'utf8' COLLATE 'utf8_general_ci';", $link, PMA_DBI_QUERY_STORE);
        }
    }

par

    // Skip charsets for Drizzle - [modif oto] support for utf8mb4 four bytes characters
    if (!PMA_DRIZZLE) {
        if (! empty($GLOBALS['collation_connection'])) {
            PMA_DBI_query("SET CHARACTER SET 'utf8mb4';", $link, PMA_DBI_QUERY_STORE);
            PMA_DBI_query("SET collation_connection = '" . PMA_sqlAddslashes($GLOBALS['collation_connection']) . "';", $link, PMA_DBI_QUERY_STORE);
        } else {
            PMA_DBI_query("SET NAMES 'utf8mb4' COLLATE 'utf8mb4_general_ci';", $link, PMA_DBI_QUERY_STORE);
        }
    }

Dans la page d'accueil de PhpMyAdmin, vérifier et changer éventuellement :

//Interclassement pour la connexion MySQL// **utf8mb4_unicode_ci**

Accepter les caractères utf8 sur quatre octets dans les messages FluxBB

Ne pourra fonctionner QUE pour une version MySQL supérieure à 5.5.3

Créer un fichier forum/db_update_oto.php qui contient :

<?php
define('PUN_ROOT', dirname(__FILE__).'/');
include PUN_ROOT.'config.php';
// Load the functions script
require PUN_ROOT.'include/functions.php';
// Load DB abstraction layer and try to connect
require PUN_ROOT.'include/dblayer/common_db.php';
 
//TRUNCATE search tables (Vide les tables search)
$db->query('TRUNCATE '.$db->prefix.'search_cache') or error('Unable to TRUNCATE search_cache.', __FILE__, __LINE__, $db->error());
$db->query('TRUNCATE '.$db->prefix.'search_matches') or error('Unable to TRUNCATE search_matches.', __FILE__, __LINE__, $db->error());
$db->query('TRUNCATE '.$db->prefix.'search_words') or error('Unable to TRUNCATE search_words.', __FILE__, __LINE__, $db->error());
 
//Convert tables to utf8mb4 charset (Converti les tables en utf8mb4)
$oto_tables = array(
'bans',
'categories',
'censoring',
'forums',
'forum_perms',
'groups',
'online',
'posts',
'ranks',
'reports',
'search_cache',
'search_matches',
'search_words',
'topics',
'users'
);
for($oto_i=0;$oto_i < count($oto_tables);$oto_i++) {
 $oto_collate = 'general_ci';
 if($oto_tables[$oto_i] == 'search_words') $oto_collate = 'bin';
 $db->query('ALTER TABLE `'.$db->prefix.$oto_tables[$oto_i].'` CONVERT TO CHARSET utf8mb4 COLLATE utf8mb4_'.$oto_collate) or error('Unable to set table charset utf8', __FILE__, __LINE__, $db->error());
}
?>

Dans le fichier forum/include/dblayermysql.php

Remplacer

		// Setup the client-server character set (UTF-8)
		if (!defined('FORUM_NO_SET_NAMES'))
			$this->set_names('utf8');

par

		// Setup the client-server character set (UTF-8)
		if (!defined('FORUM_NO_SET_NAMES'))
			$this->set_names('utf8mb4');

Filtrer les caractères utf8 sur quatre octets dans les messages FluxBB

Note : Filtrage effectif à partir de FluxBB 1.4.8

Il peut arriver que des caractères utf-8 à quatre octets soient insérés dans les messages par les utilisateurs. Cela va, en fonction de la configuration du verveur :

  • soit générer une erreur MySQL et le message ne sera pas enregistré
  • soit tronquer le message juste avant le caractère utf-8 à quatre octets

Pour éviter cela, on peut nettoyer le message et remplacer les caractères utf-8 à quatre octets par le caractère ?

Dans le fichier post.php, juste après :

   $now = time();

ajouter :

//modif oto - Replace bad character by '?' including utf8 four bytes 
$message = preg_replace('/[x00-x08x10x0Bx0Cx0E-x19x7F]'.
 '|[x00-x7F][x80-xBF]+'.
 '|([xC0xC1]|[xF0-xFF])[x80-xBF]*'.
 '|[xC2-xDF]((?![x80-xBF])|[x80-xBF]{2,})'.
 '|[xE0-xEF](([x80-xBF](?![x80-xBF]))|(?![x80-xBF]{2})|[x80-xBF]{3,})/S',
 '?', $message );
$message = preg_replace('/xE0[x80-x9F][x80-xBF]'.
 '|xED[xA0-xBF][x80-xBF]/S','?', $message );
//En modif oto
 
mysql_et_utf8_quatre_octets.txt · Dernière modification: 2012/07/27 17:44 par Otomatic