PHPで文字列の長さを取得する関数には strlen() と mb_strlen() があります。日本語を扱うと同じ文字列でも返る値が違うため、用途に合わせた選択が必要です。この記事では両者の違いと、「正確に」数えるためのポイントを解説します。
この記事の結論:
strlen() はバイト数、mb_strlen() は文字数を返します。日本語などの「文字数」を数えるなら mb_strlen() を使ってください。バイト数が必要な場面(DBの容量・バイト制限)では strlen() が役立ちます。strlen():バイト数を取得する
strlen() は文字列のバイト数を返します。半角英数字は1文字=1バイトなので、英数字なら見た目の文字数と一致します。
strlen(英数字なら文字数と一致)
<?php
echo strlen("Hello"); // 5
しかし日本語などの多バイト文字では、文字数とは異なる値になります。
日本語ではバイト数になる
<?php
echo strlen("こんにちは"); // 15(UTF-8で1文字3バイト × 5文字)
mb_strlen():文字数を取得する
「文字数」を正確に数えたいときは mb_strlen() を使います。マルチバイト対応で、日本語でも見た目の文字数を返します。
mb_strlen(文字数)
<?php
echo mb_strlen("こんにちは"); // 5
echo mb_strlen("こんにちは", "UTF-8"); // 5(エンコーディング明示も可)
第2引数のエンコーディングは省略可能で、省略すると内部エンコーディング(通常UTF-8)が使われます。環境がUTF-8なら省略しても問題ありません。
バイト数と文字数の使い分け
| 知りたいこと | 関数 |
|---|---|
| 表示・入力チェックの「文字数」 | mb_strlen() |
| DBのVARCHAR容量・バイト制限 | strlen() |
| ファイルサイズ・通信量の見積り | strlen() |
たとえば「全角・半角を問わず20文字まで」の入力制限なら mb_strlen()、バイト数で制限のあるDBカラムに収まるか確認するなら strlen() を使います。
さらに正確に:結合文字・絵文字(書記素)
厳密には mb_strlen() が数えるのはコードポイント数であり、「見た目の文字数」とは限りません。たとえば「é」を「e + アクセント記号(結合文字)」で表現した場合、見た目は1文字でも mb_strlen() は2を返します。一部の絵文字(複数のコードポイントを結合したもの)も同様に複数として数えられます。
結合文字はコードポイント単位で数える
<?php
// "é" を「e + 結合アクセント(U+0301)」で表したもの
$combined = "e\u{0301}"; // 見た目は é(1文字)
echo mb_strlen($combined); // 2(コードポイント数)
見た目の文字数(書記素クラスタ)を数えたい場合は、intl拡張の
grapheme_strlen() を使います(結合文字や絵文字を「1つ」として数えます)。通常の日本語テキストでは mb_strlen() で十分です。よくある質問(FAQ)
Qstrlenとmb_strlenはどう使い分けますか?
A「文字数」を知りたいなら
mb_strlen()、「バイト数」を知りたいなら strlen() です。日本語の文字数カウントには mb_strlen() を使ってください。Qstrlenで日本語が文字数と違う値になります。
A
strlen() はバイト数を返すためです。UTF-8では日本語1文字が3バイトなので、「こんにちは」は 15 になります。文字数なら mb_strlen() を使ってください。Qmb_strlenの第2引数は必須ですか?
A必須ではありません。省略すると内部エンコーディング(通常UTF-8)が使われます。明示する場合は
mb_strlen($s, "UTF-8") と書きます。Q絵文字や結合文字で数がおかしくなります。
A
mb_strlen() はコードポイント数を数えるためです。結合文字や複数コードポイントの絵文字は複数として数えられます。見た目どおりに数えたい場合は intl拡張の grapheme_strlen() を使います。まとめ
PHPで文字列の長さを取得するポイントを整理します。
strlen()はバイト数、mb_strlen()は文字数- 日本語の文字数カウントは
mb_strlen() - DBのバイト制限などバイト数が必要なら
strlen() - mb_strlenの第2引数(encoding)は省略可(既定UTF-8相当)
- 結合文字・絵文字を見た目どおり数えるなら
grapheme_strlen()(intl)
関連として、substrとmb_substrの使い方・Uninitialized string offset エラーの解決方法・文字列パターンの確認方法もあわせて読むと、PHPの文字列処理に強くなれます。
