Multibyte String ProcessingにPHPを使用する場合、 MB_GET_INFO()とMB_STRTOLOWER()は、2つの一般的なマルチバイト関数です。ただし、これらの2つの機能が一緒に使用されると、文字セットの設定が無視されている場合、特に中国語、日本、ロシア語などの非ASSASCII文字を扱う場合、予期しない文字列処理の問題が発生する可能性があります。
この記事では、一般的な問題と、正しい文字セット構成でそれらを回避する方法について説明します。
PHPのMB_STRTOLOWER()関数は、マルチバイト文字列を小文字に変換するために使用されますが、現在のマルチバイト文字セット環境に依存しています。この環境はMB_INTERNAL_ENCODING()によって設定されており、関数が呼び出されたときに文字セットパラメーターを渡すことでオーバーライドすることもできます。
MB_GET_INFO()関数は、デフォルトの文字セット情報を含む現在のマルチバイト構成を取得するために使用されます。 MB_STRTOLOWER()が不適切な文字セット構成で呼び出される場合、マルチバイト文字列(特にUTF-8)を処理するときに、文字化けコードまたは誤った変換が発生する可能性があります。
典型的な例は次のとおりです。
<?php
mb_internal_encoding("ISO-8859-1"); // 誤って非設定されています UTF-8 コーディング
$str = "üBERGANG";
$lower = mb_strtolower($str); // 文字セットは指定されていません
echo $lower;
?>
出力は予想されるübergangではなく、むしろ文字化けしたり変更されたりしないかもしれません。これは、現在の文字セットがUTF-8ではなく、関数がマルチバイト文字を正しく認識しないためです。
MB_GET_INFO()を使用して、現在のエンコード設定を表示します。
<?php
print_r(mb_get_info());
?>
出力の「内部_ENCODING」フィールドがキーであり、ここで「UTF-8」でない場合、環境が多言語コンテンツの処理に適していない可能性があることを意味します。
<?php
mb_internal_encoding("UTF-8"); // グローバルに設定されています UTF-8
$str = "üBERGANG";
$lower = mb_strtolower($str);
echo $lower; // 出力:übergang
?>
<?php
$str = "üBERGANG";
$lower = mb_strtolower($str, "UTF-8");
echo $lower; // 出力:übergang
?>
この方法はより堅牢であり、システムのデフォルトエンコードがUTF-8でなくても影響を受けません。
Webフォーム、API、データベースなどからの入力データを処理する場合、エンコードの統合を無視するのはしばしば簡単です。たとえば、フロントエンドではUTF-8エンコードを使用して文字列を通過しますが、バックエンドPHP環境は依然としてISO-8859-1を使用しているため、文字列操作が失敗します。
したがって、システム全体がUTF-8エンコードを均一に使用することを保証することが、そのような問題を回避するための基本的な方法です。
mb_get_info()を使用して構成を表示し、 「internal_encoding」が「utf-8」であることを確認します。
常に明示的に文字セットをマルチバイト関数に渡し、デフォルト値への依存性を回避します。
追加など、入り口にセットを設定します。
mb_internal_encoding("UTF-8");
mb_http_output("UTF-8");
mb_regex_encoding("UTF-8");
URLパラメーターを処理するときは、 MB_CONVERT_ENCODING()を使用して入力を変換してください。たとえば、次のようにしてください。
$url = "https://gitbox.net/über";
$url_utf8 = mb_convert_encoding($url, "UTF-8", "auto");
一般的な文字セットの問題は、通常、MB_GET_INFO( )と組み合わせて使用する場合、UTF-8ではなくデフォルトのエンコードに起因します。これらの問題は、文字セットを均一にチェックおよび設定するか、関数を呼び出すときに文字セットを手動で指定し、多言語テキストを処理するときにプログラムの精度と安定性を確保することにより、効果的に回避できます。
キャラクターセットのカオスは、国際プロジェクトで最も隠されているが致命的な問題の1つであることを常に覚えておいてください。エンコーディングを明示的にセットアップすることを恐れるよりも、より複雑になりたいです。予防はデバッグよりもはるかに優れています。