PHPで文字列の長さを正確に取得する方法|strlenとmb_strlenの違い

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で日本語が文字数と違う値になります。
Astrlen()バイト数を返すためです。UTF-8では日本語1文字が3バイトなので、「こんにちは」は 15 になります。文字数なら mb_strlen() を使ってください。
Qmb_strlenの第2引数は必須ですか?
A必須ではありません。省略すると内部エンコーディング(通常UTF-8)が使われます。明示する場合は mb_strlen($s, "UTF-8") と書きます。
Q絵文字や結合文字で数がおかしくなります。
Amb_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の文字列処理に強くなれます。