WEBやメールで文字化けに出会ったことがありませんか?
文字化けを目にすると、「ウィルスに感染したのでは?」とか「ソフトのバグが発生したのでは?」とか心配になりますよね。
文字化けは、文字データと文字の符号化方式のミスマッチで発生するものです。文字データを適切に文字エンコーディングして文字化けを防ぎたいものです。
ここでは、PHPで文字を扱うための基礎知識として、文字コードとはどういうものか、どんな種類かあるのかを整理し、そのうえで、PHPのおもな文字エンコーディング関数の使い方について解説します。
PHPで文字データを正しく扱うための参考に、ぜひ読んでみてください。
目次
文字コードの基礎知識
PCやスマホでは当たり前のように日本語の文章を利用していますが、それができるのも、文字コードが整備されてきたからです。
まず、文字コードの基礎について紹介します。
文字コードとは?
文字コードは、コンピュータで文字を処理するためにコンピュータ内でどのような数値表現にするかを取り決めたものです。具体的には、文字集合と符号化方式から成り立っています。
文字集合は、コンピュータ処理の対象とする文字を登録したいわば文字一覧です。代表的なものに、JISX0208やunicodeがあります。
符号化方式は、文字集合における番号をコンピュータ内部で処理する数値(バイト表現)に変換するための規則です。エンコーディングルールとも呼ばれます。
符号化方式のことを文字コードと呼ぶことが多いようです。ASCIIやSHIFT-JIS、EUCやUTF-8などがよく使われます。
コンピュータが生まれた当初はASCIIコードでカバーしている英数字や記号や制御文字などの少数の文字しか扱いませんでした。
コンピュータが普及するにつれて世界中の言語をサポートできるように、文字集合に漢字やひらがななどを含め多くの文字が追加されました。それらを扱うための符号化方式もOSごとに個別に設定されるなど増えました。
こうして多くの文字コードが混在することとなり、文字コード間の変換がうまくいかないといわゆる文字化けが発生するのです。
主要な文字コード
おもな文字コードとして、ASCII、SHIFT-JIS、EUSーJP、UTF-8について説明します。
ASCIIコード
- ・バイト(7ビット)の文字集合です。半角英数記号文字と制御文字を定義しています。
- ・JISコード 電子メールなどで利用されています。
- ・ESC(0x1B) で始まるエスケープシーケンスで、その後に続く文字集合を指定します。
- ・全角文字は、区点番号にそれぞれ 0x20 を加えた数値となります。
SHIFT-JIS
- ・Windows 系で使用されています。
- ・ASCIIコードに加え、日本語の文字を加えています。
- ・半角カタカナは1バイトで表現し、それ以外の全角文字は、2バイトで表現します。
- ・SHIFT-JISを拡張したMS932がwindowsで使用されています。
EUC-JP
- ・UNIX/Linix 系のシステムで使用されています。
- ・ASCII、JIS X 0208(漢字)、JIS X 0201(半角カナ) を扱います。
- ・漢字は区点番号に 0xA0 を足します。半角カナは SS2(0x8E) を付加します。
UTF-8
- ・ASCIIコードの文字に加え、世界中の文字を加えたunicodeの符号化方式です。
- ・ASCIIコードで以外の文字は、2~6バイトで表現し、日本語の文字は、基本的に3バイトで表現します。
unicodeは複雑
unicodeは厳密には文字集合であって文字コードではないことをすでに説明した通りです。
なにしろ、世界中で使用されている文字を集めて登録するのですから、膨大な個数の文字を扱うことになります。
unicodeでは、1文字を2つの文字集合の要素で表現することができます。例えば、「ガ」を「カ」と「゛」の2要素であらわという具合です。したがって、unicodeでは文字数をカウントするのが面倒です。
さらに、unicodeに関する符号化方式には、UTF-8、UTF-16、UTF-32など複数の方式があります。現在は、UTF-8を利用することがデファクトとなっています。
文字化けとは?
文字化けとは、文字コード変換に失敗して、「?」などの文字が表示されるという現象です。
これは、各文字コードごとにサポートする文字の範囲が異なっているため、変換できずに代替文字が割り当てられるためです。
特にSHIFT-JISとUTF-8の変換で発生しやすいです。例えば、ベンダー固有設定を含むSHIFT-JISの外字領域の文字は、UTF-8ではサポートされない場合があります。
PHPで文字コードを変換するには
PHPの文字エンコーディング関連の関数を紹介します。
WindowsではSHIFT-JIS、UNIXではEUCーJPを扱うことが多いため、UTF-8の採用が多いWEBとは符号化方式が異なります。WindowsやUNIXで作成されたファイルなどから入力する場合は、文字エンコーディングが必要です。
mb_convert_encodingの使い方
文字コード変換には、マルチバイト文字列処理関数のmb_convert_encodingを使用します。
1 |
mb_convert_encoding ( array|string $string , string $to_encoding , array|string|null $from_encoding = null ) : array|string|false |
第1引数($string) | 変換したい文字列を指定します。 配列を指定した場合は、すべての要素が変換されます。 |
第2引数($to_encoding) | 変換後の文字コードを指定します。 |
第3引数($from_encoding) | 変換前の文字コードを指定します。 配列またはカンマ区切りの文字列により、複数の文字コードを指定できます。その場合は先頭からチェックします。 省略可能です。省略した場合は内部エンコーディングの文字コードが設定されます。 |
戻り値 | 変換成功時は変換後の文字列が戻されます。 変換失敗時はfalseが戻されます。 |
第2引数および第3引数で使用できる文字コードには以下のようなものがあります。
設定値 | ”UTF-8” | “SJIS” | ”SJIS-WIN” | “EUC-JP” | ”JIS” |
文字コード | UTF-8 | シフトJIS | シフトJIS(Windows) | EUCコード | JISコード |
詳しくは、PHPマニュアル:サポートされる文字エンコーディングを参照ください。
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?php echo "<br>"."mb_convert_encoding"."<br>".PHP_EOL; /* テスト用の文字列 */ $str = "AΩ語"; echo $str." : ".bin2hex($str)."<br>".PHP_EOL; /* 内部文字エンコーディングからSJISに変換 */ $str = mb_convert_encoding($str, "SJIS"); //結果を文字と16進数で表示 echo $str." : ".bin2hex($str)."<br>".PHP_EOL; /* EUC-JPからUTF-8に変換 */ $str = file_get_contents("euc.txt"); $str = mb_convert_encoding($str, "UTF-8", "EUC-JP"); //結果を文字と16進数で表示 echo $str." : ".bin2hex($str)."<br>".PHP_EOL; /* JIS, eucjp-win, sjis-winの順番で自動検出し、UTF-8に変換 */ $str = file_get_contents("euc.txt"); $str = mb_convert_encoding($str, "UTF-8", "JIS, eucjp-win, sjis-win"); //結果を文字と16進数で表示 echo $str." : ".bin2hex($str)."<br>".PHP_EOL; /* "auto" は、"ASCII,JIS,UTF-8,EUC-JP,SJIS" に展開される */ $str = file_get_contents("euc.txt"); $str = mb_convert_encoding($str, "UTF-8", "auto"); //結果を文字と16進数で表示 echo $str." : ".bin2hex($str)."<br>".PHP_EOL; ?> |
結果
1 2 3 4 5 6 |
mb_convert_encoding AΩ語 : 41cea9e8aa9e A���� : 4183b68cea AΩ語 : 41cea9e8aa9e AΩ語 : 41cea9e8aa9e AΩ語 : 41cea9e8aa9e |
mb_convert_encodingに関連するPHP関数
文字エンコーディングに使用するマルチバイト文字列関連の関数を紹介します。
mb_check_encoding | 指定したエンコーディングで有効なものかどうかを調べる |
使用例
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php echo "<br>"."mb_check_encoding"."<br>".PHP_EOL; //SHIFT-JISで保存されたファイルから読み込む $sjis = file_get_contents("sjis.txt"); //SHIFT-JISでエンコーディングできることを確認 $enc="SJIS"; if(mb_check_encoding($sjis,$enc)) { echo $enc." encoding:Good!"."<br>".PHP_EOL;} else { echo $enc." encoding:Bad!"."<br>".PHP_EOL;}; ?> |
結果
1 2 |
mb_check_encoding SJIS encoding:Good! |
mb_detect_encoding | 文字エンコーディングを検出する |
使用例
1 2 3 4 5 6 7 8 9 10 |
<?php echo "<br>"."mb_detect_encoding"."<br>".PHP_EOL; //SHIFT-JISで保存されたファイルから読み込む $sjis = file_get_contents("sjis.txt"); /* "auto" は mbstring.language の設定を使って展開されます */ echo mb_detect_encoding($sjis, "auto")."<br>".PHP_EOL; /* 文字エンコーディングをカンマ区切りのリストで指定することで、encodings 引数を指定 */ echo mb_detect_encoding($sjis, "JIS, eucjp-win,sjis-win, sjis")."<br>".PHP_EOL; ?> |
結果
1 2 3 |
mb_detect_encoding SJIS SJIS-win |
mb_detect_order | 文字エンコーディング検出順序を設定あるいは取得する |
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php echo "<br>"."mb_detect_order"."<br>".PHP_EOL; //SHIFT-JISで保存されたファイルから読み込む $sjis = file_get_contents("sjis.txt"); /* 現在の検出順を表示 */ mb_detect_order("eucjp-win,sjis-win,UTF-8"); echo implode(", ", mb_detect_order())."<br>".PHP_EOL;/* リストで検出順を設定 */ /* 配列で検出順を設定 */ $ary[] = "ASCII"; $ary[] = "JIS"; $ary[] = "EUC-JP"; mb_detect_order($ary); echo implode(", ", mb_detect_order())."<br>".PHP_EOL;/* リストで検出順を設定 */ ?> |
結果
1 2 3 |
mb_detect_order eucJP-win, SJIS-win, UTF-8 ASCII, JIS, EUC-JP |
mb_list_encodings | サポートするすべてのエンコーディングの配列を返す |
使用例
1 2 3 4 |
<?php echo "<br>"."mb_list_encodings"."<br>".PHP_EOL; print_r(mb_list_encodings())."<br>".PHP_EOL; ?> |
結果
1 2 |
mb_list_encodings Array ( [0] => wchar [1] => ・・・ [81] => CP50220 [82] => CP50220raw [83] => CP50221 [84] => CP50222 ) |
mb_internal_encoding | 内部文字エンコーディングを設定あるいは取得する |
使用例
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php //SHIFT-JISで保存されたファイルから読み込む $sjis = file_get_contents("sjis.txt"); echo "<br>"."mb_internal_encoding"."<br>".PHP_EOL; /* 現在の内部文字エンコーディングを表示 */ echo mb_internal_encoding()."<br>".PHP_EOL; /* 内部文字エンコーディングをUTF-8に設定 */ mb_internal_encoding("UTF-8"); /* 設定を確認 */ echo mb_internal_encoding()."<br>".PHP_EOL; ?> |
結果
1 2 3 |
mb_internal_encoding UTF-8 UTF-8 |
PHPで文字コードを扱う際の留意事項
SHIFT-JISには sjis と sjis-win があります。sjis-winはWindows用で使われているシフトJISです。一部の文字は sjis-win でないと文字化けを起こすことがあります。mb_convert_encoding()の sjis で文字化けを起こすときには sjis-win を使ってみましょう。
まとめ
いかがでしたか?今回は、PHP文字エンコード関数のmb_convert_encodingについて説明しました。
WEBではUTF-8を使用することが一般的になってきましたが、まだまだ、それ以外の文字コードを使ったリソースが多数あり、文字化けに対処するためにも文字コード変換は必要です。
この記事が、WebプログラミングやPHPの学習などのお役に立てば幸いです。