プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
PHP、mb_strlen()関数で日本語の文字数が正常に取れなかった話
結論から書くと

mb_strlen($str, 'UTF-8')

のように、第2引数に文字列の文字エンコーディングを指定したら大丈夫でした。

それでは詳細……と言うほどでもないですが、詳細を書いていきます。

マルチバイト文字列の文字数を取得しようと思いましてね。
mb_strlen()関数を使って、こんなコードを実行したところφ(--)

<?php

$str = 'ぴよぴよ太郎';
print '「' . $str . '」の文字数:' . mb_strlen($str);

こんな結果が表示されたのですφ(--)

「ぴよぴよ太郎」の文字数:7

……「ぴよぴよ太郎」は7文字じゃないよ(--?

ほんで、あれやこれやと調べたところ
PHPの内部エンコーディングが文字列のエンコーディングと合っていないと
こんな現象が発生し得ると分かりました。

どれどれ、本当かな?

内部エンコーディングはmb_internal_encoding()関数で取得できるので
コマンドラインからこんなコードを実行してみましたφ(--)

C:\test\php.exe -r "print mb_internal_encoding();";

素直に、こんなスクリプトファイルを用意して実行しても良いですφ(--)

<?php
print mb_internal_encoding();

結果は、こうなりましたφ(--)

UTF-8

なんだよ、内部エンコーディングは
ちゃんとUTF-8になってるじゃねーか(-A-)

……と思ったのですが、PHPのプログラムファイルの方がShift_JISでした。
あぁ、確かに文字エンコーディングが合ってねーや(ノ∀`)

つまり、Shift_JISとして文字数を数えて欲しかったのに、UTF-8として数えていたってことですね。
そのため、6文字と判断すべきところを7文字と判断しやがったようです。

解決方法は、内部エンコーディングと文字列のエンコーディングを合わせることです。

ですから、PHPのプログラムファイルをUTF-8にしても解決します。
……が、一般的にはmb_strlen()関数の第2引数に文字列の文字エンコーディングを指定して

mb_strlen($str, 'SJIS')

とか、やります。

ということで、こんな風にしたらφ(--)

<?php

$str = 'ぴよぴよ太郎';
print '「' . $str . '」の文字数:' . mb_strlen($str, "SJIS");

こんな結果になりましたφ(--)

「ぴよぴよ太郎」の文字数:6

うん。
「ぴよぴよ太郎」は6文字です。
おっけー、おっけー。

それにしても、これは注意が必要ですね。
エラーにならないので、気付かないままバグを仕込みかねません。
個人的には

mb_strlen()関数を使うときは、必ず第2引数を指定する

癖を付けておいた方が、無難だと思います。

取りあえず、そんな感じ\(--)/
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:● PHP  thema:システム開発 - genre:コンピュータ  Posted by ササキマコト 

  関連記事