全角文字の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) (2009/06/30) 鈴木 憲治安藤 建一 商品詳細を見る |
- 関連記事
-
- 継承できるテンプレート「Twig」
- CodeIgniterのMatchBoxとHMVC
- 祝!1万部超え『PHP逆引きレシピ』プレゼントキャンペーン
- CodeIgniterをHMVCでモジュール化
- PHPで文字コードをSJISからUTF8に変換する方法
- PHPで配列の重複を削除する方法
- Fatal error: Allowed memory size of 16777216 bytes exhausted
- PHPのstrlen関数で全角文字が3バイトになる件
- PHPでファイル一括削除
- PHPで日時の大小比較
- CodeIgniter 1.7.1 日本語化パック
- AmazonのASINで、36進数を10進数へ変換
- PHPの正規表現
- MatchBox for CodeIgniter 使い方
- PHPでディレクトリの容量を計算する方法