Passer au contenu principal
Unicode et graphèmes clusters
                   pour PHP
   Unicode : bases et concepts

   Unicode : état de lřart

   PatchworkUtf8




                                                         PHP Tour Ŕ Nantes 2012
                                  https://github.com/nicolas-grekas/Patchwork-UTF8
Peace


和平      ☮




                                   PHP Tour Ŕ Nantes 2012
            https://github.com/nicolas-grekas/Patchwork-UTF8
P      U+0050
                         LATIN CAPITAL LETTER P
                                                            U+0633
                                                            ARABIC LETTER SEEN




                  和      U+548C
                         CJK UNIFIED IDEOGRAPH-548C   ☮     U+262E
                                                            PEACE SYMBOL




   A chaque caractère son numéro, un nom et des propriétés (catégorie, script, etc.)




                                                                                   PHP Tour Ŕ Nantes 2012
                                                            https://github.com/nicolas-grekas/Patchwork-UTF8
   Représentations binaires
   Majuscules, minuscules, folding
   Compositions, ligatures
   Comparaison : normalisations et collations
   Segmentation : caractères, mots, phrases et césures

   Locales : conventions culturelles, translittérations
   Identifiants et sécurité, confusables
   Affichage : direction, largeur



                                                             PHP Tour Ŕ Nantes 2012
                                      https://github.com/nicolas-grekas/Patchwork-UTF8
á      U+00E1

   De point de code                     UTF-16BE
                                                        LATIN SMALL LETTER A WITH ACUTE

                                                        00 E1

    à séquence dřoctets                      UTF-8      C3 A1


    ◦ UTF-8 : 1, 2, 3 ou 4 octets
    ◦ UTF-16 : 2 ou 4 octets                  あ         U+3042
                                                        HIRAGANA LETTER A


    ◦ UTF-32 : 4 octets                  UTF-16BE       30 42
                                             UTF-8      E3 81 82




    BOM U+FEFF
                                         UTF-32BE       00 00 FE FF
                                        UTF-32LE       FF FE 00 00

    Byte Order Mark                      UTF-16BE
                                         UTF-16LE
                                                        FE FF
                                                        FF FE
                                             UTF-8      EF BB BF ()




                                                           PHP Tour Ŕ Nantes 2012
                                    https://github.com/nicolas-grekas/Patchwork-UTF8
Octet 1    Octet 2    Octet 3        Octet 4

         0xxxxxxx

         110xxxxx   10xxxxxx

         1110xxxx   10xxxxxx   10xxxxxx

         11110xxx   10xxxxxx   10xxxxxx     10xxxxxx



   Sur-ensemble dřASCII
   Auto-synchronisé
   Caractéristique


                                                                 PHP Tour Ŕ Nantes 2012
                                          https://github.com/nicolas-grekas/Patchwork-UTF8
   Concerne un peu plus de 1000 caractères

   Folding Ŕ comparaison insensible à la casse
    ◦   Comparer les chaînes en minuscules
    ◦   Une majuscule, deux minuscules : Σ ⇔ σ/ς
    ◦   Exception turque : I ⇔ i vs İ ⇔ i et I ⇔ ı
    ◦   Full folding : ß ⇔ ss




                                                              PHP Tour Ŕ Nantes 2012
                                       https://github.com/nicolas-grekas/Patchwork-UTF8
Å
               Å
                            U+00C5
                            LATIN CAPITAL LETTER A WITH RING ABOVE

                     A+◌̊   0041, 030A
                            LATIN CAPITAL LETTER A, COMBINING RING ABOVE




                      f+i
                fi
                            U+0066, U+0069
                            LATIN SMALL LETTER F, LATIN SMALL LETTER I

                       fi    FB01
                            LATIN SMALL LIGATURE FI




                            U+1103, U+116E, U+11A8
                    ᄃ+ᅮ+ᆨ
               둑
                            HANGUL CHOSEONG TIKEUT, HANGUL JUNGSEONG U,
                            HANGUL JONGSEONG KIYEOK

                      둑     U+B451
                            HANGUL SYLLABE DUG




   Comment tester lřégalité ? (=, ≠)


                                                                             PHP Tour Ŕ Nantes 2012
                                                      https://github.com/nicolas-grekas/Patchwork-UTF8
   Forme Composée, Décomposée, de Kompatiblité

                           U+1E0B, U+0323
                   ḋ+◌     LATIN SMALL LETTER D WITH DOT ABOVE,
                           COMBINING DOT BELOW
                           U+0064, U+0323, U+0307
                  d+◌+◌̇   LATIN SMALL LETTER D,
                           COMBINING DOT BELOW, COMBINING DOT ABOVE
                                                                               NFD

                           U+1E0D, U+0307
                   ḍ+◌̇    LATIN SMALL LETTER D WITH DOT BELOW,
                           COMBINING DOT ABOVE
                                                                               NFC




                    f+i
              fi
                           U+0066, U+0069
                           LATIN SMALL LETTER F, LATIN SMALL LETTER I          NFKD, NFKC

                     fi     U+FB01
                           LATIN SMALL LIGATURE FI                             NFD, NFC




                                                                            PHP Tour Ŕ Nantes 2012
                                                     https://github.com/nicolas-grekas/Patchwork-UTF8
   NFC
                      D        é        j        à
                    U+0044   U+00E9   U+006A   U+00E0

   NFD
            D        e        ◌        j        a             ◌
           U+0044   U+0065   U+0301   U+006A   U+0061       U+0300




   Quel est le 2e caractère ? le 3e ?




                                                                       PHP Tour Ŕ Nantes 2012
                                                https://github.com/nicolas-grekas/Patchwork-UTF8
   ICU : Java et C/C++
    ◦ Licence X-like, soutenu par IBM, utilisé comme
      implémentation de référence pour Unicode et +

   Perl 6 Parrot : NFG
    ◦ NFC + Graphèmes Clusters

   JavaScript : Unicode   (NFC)


   Python : chaînes typées

   PHP : iconv, mbstring, pcre, intl


                                                               PHP Tour Ŕ Nantes 2012
                                        https://github.com/nicolas-grekas/Patchwork-UTF8
NFC : Déjà
                                                                    NFD : De◌         ◌



   iconv_set_encoding('UTF-8')

    ◦   iconv($in_charset , $out_charset , $str)
    ◦   iconv_strlen($str)
    ◦   iconv_substr($str, $start, $length)
    ◦   iconv_strpos($haystack, $needle, $offset = 0)
    ◦   iconv_strrpos($haystack, $needle)

   Manipulation de chaînes UTF-8 : fait !



                                                              PHP Tour Ŕ Nantes 2012
                                       https://github.com/nicolas-grekas/Patchwork-UTF8
NFC : Déjà
                                                                  NFD : De◌ ja◌



   mb_internal_encoding('UTF-8')

    ◦ Équivalents dřiconv
    ◦ mb_strtolower/upper (), pas de folding
    ◦ mb_stripos(), folding simple




   Manipulation de chaînes UTF-8 : fait ! (bis)
   Manipulation de la casse : fait ! % folding


                                                            PHP Tour Ŕ Nantes 2012
                                     https://github.com/nicolas-grekas/Patchwork-UTF8
NFC : Déjà
                                                                     NFD : De◌         ◌



   Avec le modificateur u : /./u
   Donne accès aux propriétés Unicode
    ◦   x{00E9} ou simplement é ssi source UTF-8
    ◦   p{Greek}
    ◦   p{Mn}
    ◦   X ⇔ (?>PMpM*) pour PCRE < 8.32

   Vérifier la validité UTF-8 de $str :
                  preg_match('//u', $str)

   Manipulation de chaînes UTF-8 : fait ! (ter)
   Manipulation des propriétés Unicode : fait !

                                                               PHP Tour Ŕ Nantes 2012
                                        https://github.com/nicolas-grekas/Patchwork-UTF8
   Normalizer

   Gestion des graphèmes clusters

   Collator, NumberFormatter, Locale,
    MessageFormatter, IntlDateFormatter,
    Spoofchecker, Transliterator, Fonctions IDN,
    Uconverter (PHP5.5)




                                                        PHP Tour Ŕ Nantes 2012
                                 https://github.com/nicolas-grekas/Patchwork-UTF8
NFC : Déjà
                                                                 NFD : De◌         ◌



   use Normalizer as n;

   n::isNormalized($str, $form = n::NFC)

   n::normalize($str, $form = n::NFC)

   n::NFC, n::NFD, n::NFKC, n::NFKC, n::NONE


   Tester lřégalité de chaînes : fait !


                                                           PHP Tour Ŕ Nantes 2012
                                    https://github.com/nicolas-grekas/Patchwork-UTF8
NFC : Déjà
                                                                             NFD : De◌         ◌



   grapheme_extract ŕ Extrait un groupe de graphèmes d'une chaîne UTF-8
   grapheme_stripos
   grapheme_stristr
   grapheme_strlen
   grapheme_strpos
   grapheme_strripos
   grapheme_strrpos
   grapheme_strstr
   grapheme_substr

   Manipulation par graphème cluster : fait !
    ◦ Encore un peu jeune, attention aux bugs
    ◦ https://bugs.php.net/55562, 61860 et 62759



                                                                       PHP Tour Ŕ Nantes 2012
                                                https://github.com/nicolas-grekas/Patchwork-UTF8
   Chaînes UTF-8 : iconv, mbstring, pcre
   Casse : mbstring
   Normalisation : intl
   Graphèmes : intl et pcre
    function toAscii($s)
    {
        if (preg_match("/[x80-xFF]/", $s))
        {
            $s = Normalizer::normalize($s, Normalizer::NFKD);
            $s = preg_replace('/p{Mn}+/u', '', $s);
            $s = iconv('UTF-8', 'ASCII//TRANSLIT', $s);
        }

        return $s;
    }


   Quid :
    ◦ Case folding ? Complexité ? Disponibilité ?



                                                                               PHP Tour Ŕ Nantes 2012
                                                        https://github.com/nicolas-grekas/Patchwork-UTF8
Unicode et graphèmes clusters
                   pour PHP
   Portabilité PHP, optimisé pour UTF-8

    ◦ Iconv : 99%

    ◦ Mbstring : les 45% nécessaires

    ◦ Intl : Normalizer et grapheme_*()

    ◦ utf8_en/decode() - Windows-1252 enhanced




                                                              PHP Tour Ŕ Nantes 2012
                                       https://github.com/nicolas-grekas/Patchwork-UTF8
   HTML5 : se substitue à ISO-8859-1
                       x0    x1    x2    x3    x4    x5    x6    x7    x8    x9   xA     xB    xC   xD   xE   xF

                  0x   NUL   SOH   STX   ETX   EOT   ENQ   ACK   BEL   BS    HT   LF     VT    FF   CR   SO     SI

                  1x   DLE   DC1   DC2   DC3   DC4   NAK   SYN   ETB   CAN   EM   SUB    ESC   FS   GS   RS   US

                  2x   SP     !     "     #     $     %    &      '     (    )     *      +    ,    -    .      /

                  3x    0     1     2     3     4     5     6    7      8    9     :      ;    <    =    >      ?

                  4x   @      A     B    C     D      E     F    G     H     I     J      K    L    M    N      O

                  5x    P    Q      R     S     T     U     V    W      X    Y    Z       [        ]    ^      _

                  6x    `     a     b     c     d     e     f    g      h    i     j      k    l    m    n      o

                  7x    p     q     r     s     t     u     v    w      x    y     z      {    |    }    ~    DEL

                  8x    €           ‚     ƒ     „    …      †    ※      ˆ    ‰     Š      ‹    Œ         Ţ

                  9x          Ř     ř     Ŗ     ŗ     •     Ŕ    ŕ      ˜    ™     š      ›    œ         ţ      Ÿ

                       NBS
                  Ax          ¡     ¢     £     ¤     ¥     ¦    §      ¨    ©     ª      «    ¬    -    ®      ¯
                        P

                  Bx    °    ±      ²     ³     ´     µ     ¶    ·      ¸    ¹     º      »    ¼    ½    ¾      ¿

                  Cx   À      Á    Â     Ã     Ä      Å    Æ     Ç      È    É     Ê      Ë    Ì    Í    Î      Ï

                  Dx   Ð     Ñ     Ò     Ó     Ô     Õ     Ö     ×     Ø     Ù    Ú       Û    Ü    Ý    Þ      ß

                  Ex    à     á     â     ã     ä     å    æ      ç     è    é     ê      ë    ì    í    î      ï

                  Fx    ð     ñ     ò     ó     ô     õ     ö    ÷      ø    ù    ú       û    ü    ý    þ      ÿ



                                                                                       PHP Tour Ŕ Nantes 2012
                                                           https://github.com/nicolas-grekas/Patchwork-UTF8
PatchworkUtf8


grapheme_*
                                                 Normalizer

                     mbstring
                                        xml
             iconv




                      pcre
                                                                PHP Tour Ŕ Nantes 2012
                                         https://github.com/nicolas-grekas/Patchwork-UTF8
   Les fonctions PHP, version UTF-8

    ◦ Limité au sous-ensemble qui le nécessite

    ◦ Préfixe u:: pour déclarer lřintention dans le code




                                                             PHP Tour Ŕ Nantes 2012
                                      https://github.com/nicolas-grekas/Patchwork-UTF8
NFC : Déjà
                                                                                 NFD : De◌ ja◌



   strlen - chr - ord
   substr - str_split
   strpos - strrpos - strstr - strrchr - stripos - strripos - stristr - strrichr
   strtolower - strtoupper - ucfirst - lcfirst - ucwords
   trim - ltrim - rtrim
   strtr - str_ireplace - substr_replace - str_replace déjà compatible
   strcmp - strnatcmp - strcasecmp - strnatcasecmp - strncasecmp - strncmp
   strspn - strcspn - strpbrk - substr_compare - substr_count - str_word_count -
    count_chars
   number_format - wordwrap - str_pad - strrev - str_shuffle
   utf8_encode - utf8_decode Ŕ Windows-1252 enhanced

   Manque la famille printf

   Ajoute isUtf8 - toAscii - strtocasefold - strtonatfold et nombreux workaround



                                                                           PHP Tour Ŕ Nantes 2012
                                                    https://github.com/nicolas-grekas/Patchwork-UTF8
   Quelques extras, workarounds et
    bootstrapping

   Couvert par de nombreux tests unitaires

   Licences Apache-2.0 et GPL-2.0




                                                       PHP Tour Ŕ Nantes 2012
                                https://github.com/nicolas-grekas/Patchwork-UTF8
   https://github.com/FSX/php-utf8
   Mediawiki, PhpBB, Drupal, etc.

   Différences majeures
    ◦   Gestion des graphème clusters
    ◦   API déjà documentée : cf. documentation PHP
    ◦   Bootstrapping via autoload possible
    ◦   Testable et comparable en même temps




                                                             PHP Tour Ŕ Nantes 2012
                                      https://github.com/nicolas-grekas/Patchwork-UTF8
   Editeur de code en mode UTF-8 sans BOM

   Vérifiez la validité UTF-8 de vos entrées
   Mais ne supprimez pas les caractères erronés
    ◦ javaxFFscript:alert("XSS")
    ◦ preg_match('//u', $v) or $v = u::utf8_encode($v);

   Normalisez vos entrées UTF-8 : NFC on demand

   require 'bootup.utf8.php';
   use PatchworkUtf8 as u;


                                                                PHP Tour Ŕ Nantes 2012
                                         https://github.com/nicolas-grekas/Patchwork-UTF8
   NFC repousse les graphèmes clusters

   Pour manipuler des données (cf. MySQL),
    pas les identifiants.

   A utiliser avec discernement




                                                          PHP Tour Ŕ Nantes 2012
                                   https://github.com/nicolas-grekas/Patchwork-UTF8
   Questions ?

      https://github.com/nicolas-grekas/Patchwork-UTF8
        composer : {"require": {"patchwork/utf8": "1.0.*"}}

   Unicode.org
   Wikipédia
   « PHP et UTF-8 »
    http://julp.lescigales.org/php/utf8/
   « Handling UTF-8 with PHP »
    http://www.phpwact.org/php/i18n/utf-8




                                                                PHP Tour Ŕ Nantes 2012
                                         https://github.com/nicolas-grekas/Patchwork-UTF8
PHP Tour Ŕ Nantes 2012
https://github.com/nicolas-grekas/Patchwork-UTF8
14Mo
                                           4Mo
                                           2Mo
                                             -




                       PHP Tour Ŕ Nantes 2012
https://github.com/nicolas-grekas/Patchwork-UTF8