Maison  >  Article  >  développement back-end  >  PHP : passer au multioctet

PHP : passer au multioctet

WBOY
WBOYoriginal
2024-08-12 08:35:32727parcourir

PHP: Going multibytes

Les caractères multi-octets peuvent être délicats en programmation.

Avertissement

mbstring n'est pas activé par défaut. Assurez-vous de lire cette partie avant.

Pourquoi s'embêter avec des chaînes multi-octets ?

Un document peut contenir des chaînes multi-octets. Bien que PHP dispose de nombreuses aides utiles pour les chaînes, ces aides ne sont tout simplement pas destinées aux chaînes multi-octets.

Cela provoquera probablement de vilains bugs et d'autres erreurs inattendues, surtout lorsque vous comptez les caractères.

C'est pourquoi vous préférez utiliser les fonctions de chaîne multi-octets en PHP.

De plus, de nouvelles fonctions de chaîne multi-octets, telles que mb_trim, mb_ltrim et mb_rtrim, seront disponibles dans la version 8.4 (la prochaine version de PHP au moment de la rédaction).

Pourquoi certains caractères nécessitent-ils plusieurs octets ?

L'anglais utilise le jeu de caractères ASCII, donc les lettres comme r ou s ne nécessitent qu'un seul octet.

En revanche, certaines langues utilisent des caractères qui nécessitent plus d'un octet, par exemple les caractères Han (cela peut aller jusqu'à 6 octets !).

Quelques exemples

Compter les caractères

$strings = [
    "?????",
    "チャーミング",
    "González",
];

foreach ($strings as $string) {
    echo 'strlen:' . strlen($string) . ' vs. mb_strlen:' . mb_strlen($string) . PHP_EOL;
}

Trouver un poste

echo strpos("チャーミング", "ャ"); // gives 3
echo mb_strpos("チャーミング", "ャ"); // gives 1 because 1st position is 0

Couper la ficelle

echo substr("チャーミング", 3) . PHP_EOL;// ャーミング
echo mb_substr("チャーミング", 3);// ミング

Impact sur les performances

Vous lirez peut-être que les fonctions mbstring peuvent avoir un impact significatif.

Vous pouvez même le reproduire avec le script suivant :

$cnt = 100000;

$strs = [
    'empty' => '',
    'short' => 'zluty kun',
    'short_with_uc' => 'zluty Kun',
    'long' => str_repeat('this is about 10000 chars long string', 270),
    'long_with_uc' => str_repeat('this is about 10000 chars long String', 270),
    'short_utf8' => 'žlutý kůň',
    'short_utf8_with_uc' => 'Žlutý kŮň',
];

foreach ($strs as $k => $str) {
    $a1 = microtime(true);
    for($i=0; $i < $cnt; ++$i){
        $res = strtolower($str);
    }
    $t1 = microtime(true) - $a1;
    // echo 'it took ' . round($t1 * 1000, 3) . ' ms for ++$i'."\n";

    $a2 = microtime(true);
    for($i=0; $i < $cnt; $i++){
        $res = mb_strtolower($str);
    }
    $t2 = microtime(true) - $a2;
    // echo 'it took ' . round($t2 * 1000, 3) . ' ms for $i++'."\n";

    echo 'strtolower is '.round($t2/$t1, 2).'x faster than mb_strtolower for ' . $k . "\n\n";
}

Source : bugs PHP

Les fonctions mb_* sont plus lentes, mais c'est toujours un compromis, et seul le contexte doit déterminer si vous devez utiliser ces assistants ou créer les vôtres.

Par exemple, si vous remplacez $cnt = 100000; par $cnt = 100 ; dans le script ci-dessus, les assistants mb_* sont encore beaucoup plus lents, mais l'impact final pourrait être correct dans votre cas (par exemple, 0,008 ms contre 0,004 ms).

Conclure

Vous devez prendre en compte les multioctets, surtout dans un contexte multilingue, et PHP a des assistants intégrés pour cela.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn