ようこそ!浜村拓夫の世界へ

    ブログ内検索

    最近の記事

    ブックマーク数の多い記事

    Blog Translation

    Powered By FC2ブログ

    Powered By FC2ブログ
    ブログやるならFC2ブログ


    FC2ブログ LOGIN

    with Ajax Amazon

    スポンサーサイト

    このエントリーを含むはてなブックマーク はてなブックマーク - スポンサーサイト あとで読む
    上記の広告は1ヶ月以上更新のないブログに表示されています。
    新しい記事を書く事で広告が消せます。

    PHPのstrlen関数で全角文字が3バイトになる件

    このエントリーを含むはてなブックマーク はてなブックマーク - PHPのstrlen関数で全角文字が3バイトになる件 あとで読む
    PHPのstrlen関数で、文字列のバイト数を取得しようとしたら、全角文字1文字が2バイトではなく3バイトとしてカウントされてしまった。
    全角文字の1文字=2バイト分として数えてくれないと困る。

    PHP: strlen - Manual

    strlen ― 文字列の長さを得る
    与えられた string の長さを返します。


    PHPのマニュアルでは、「日本語の全角文字1文字を2バイト」として数えるとは一言も書いていない。
    =バイト数は、文字コードに依存する。

    ●UTF-8の日本語のバイト数
    UTF-8 - Wikipedia

    日本語の文字とバイト数
    1バイト
    * ASCIIの全て、およびJIS X 0201ラテン文字の円記号とオーバライン以外

    2バイト
    * JIS X 0201の円記号
    * JIS X 0208の非漢字の一部

    3バイト
    * 上記以外のJIS X 0201の文字
    * JIS X 0208の漢字エリアの全て
    * JIS X 0212の漢字エリアの全て
    * JIS X 0213の第3・4水準漢字の一部

    4バイト
    * UnicodeのBMP以外全て
    * JIS X 0213の第3・4水準漢字の一部

    5~6バイト
    * Unicodeの範囲外(どんな文字が登録されるかという計画も無い)



    なんだ、そういうことか。
    文字コードとしてUTF-8を使っている場合、日本語の文字は1~6バイトのデータとして定義されている。
    よって、strlenで日本語の文字のバイト数を数えると、1~6バイトという答えが返ってくる。
    (BOMなしのUTF-8Nを使っているけど、文字数のカウントにBOMは関係ない?)

    原因は分かった。
    さて、どんな対策をすればいいのか?

    ●UTF-8をSJISに変換してカウント
    この方法で解決した。

    北青山通信 - from aoyama >> 全角文字は2バイトではないのでした。

    echo(strlen(mb_convert_encoding($str, ‘SJIS’, ‘UTF-8′))); // 6
    UTF-8のままですと、全角文字は2バイトにはなりません。しかも、正しく文字コードをしてあげないと正しい文字数になりません。
    一旦、シフトJISに変換してあげて、mb_stringではないstrlen()で全角文字を2バイトで計算してくれます。




    ところで、3バイト以上のデータ長を持つSJISの日本語文字ってあるのかな?
    ベンダ別 SJIS コード一覧

    ベンダ名 インフォミックス アスキー INFORMIX V6 ALS
    コード範囲 3バイト文字: 第1バイト 0xFD 第2バイト 0xA1-0xFE 第3バイト 0xA1-0xFE
    字形 規定なし


    「インフォミックス アスキー」という会社は、もう潰れてなくなってしまったようだ。
    とりあえず、SJISを3バイト目まで独自拡張しているベンダーはなさそうだからOK?

    ●bin2hex関数を使う方法
    こんな対策も紹介されていた。

    日本語文字列のバイト数取得にstrlenだけではダメな理由-PHP

    $volm = strlen(bin2hex($data)) / 2;
    // $data:バイト数を取得したいデータ
    // $volm:データ長(byte)


    bin2hexは、シングルバイト文字を16進数表記に変換する関数です。
    16進数表記の場合、シングルバイト文字1文字は必ず2文字の16進数に変換されます。
    したがって、その16進数表記の半分が、当該バイト数というわけですね。



    ↑テストしてみたら、思い通りの結果が得られなかったので、とりあえず不採用。

    全角文字=2バイトという固定観念は外さないといけないな。
    =同じ日本語でも、文字コードの体系によって、使用されているバイト数は異なると。

    PHP 逆引きレシピ (PROGRAMMER’S RECiPE)PHP 逆引きレシピ (PROGRAMMER’S RECiPE)
    (2009/06/30)
    鈴木 憲治安藤 建一

    商品詳細を見る

    関連記事

    コメント

    通りすがりで恐縮ですが・・・
    全角がダブルバイトではなくマルチバイトになった今、
    半角 = 1 全角 = 2という概念は「幅」と呼ぶようです。
    mb_strwidthで算出できますよ。

    文字幅

    有益な情報のご提供どうもありがとうございます。
    「文字幅」という数え方、単位があるんですね。
    大変参考になりました。

    コメントの投稿


    管理者にだけ表示を許可する

    トラックバック

    トラックバックURL:
    http://hamamuratakuo.blog61.fc2.com/tb.php/421-92134467

    FC2Ad

    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。