- カテゴリ: PHP
- 対応バージョン: Laravel 11/12・PHP 8.2(※指定がなかったため既定値を採用)
- 名前空間 / FQCN / コマンド: 関数
mb_strlen(string $string, ?string $encoding = null): int - 関連:
strlen/mb_substr/mb_strwidth/grapheme_strlen/mb_detect_encoding - 変更履歴: PHP 8.0 以降、無効なエンコーディング等で
ValueErrorを送出。8.1/8.2/8.3 で大きな仕様差分なし。
要点(TL;DR)
- マルチバイト文字列の**文字数(コードポイント数)**を返す。
mb_strlen('あいう', 'UTF-8') // 3- 罠:
- 見た目1文字の合成絵文字は複数カウント→ 見た目の文字数は
grapheme_strlen - バイト数ではない(DB制限は
strlenで確認) ext-mbstringが必須。無効だと関数未定義。
- 見た目1文字の合成絵文字は複数カウント→ 見た目の文字数は
概要
mb_strlen はマルチバイト文字列の長さを、エンコーディングを考慮してコードポイント数で返します。日本語や多言語テキストの入力長チェックに必須です。フォームバリデーションや API の文字数制限、ログの整形などで使用します。
構文 / シグネチャ
int mb_strlen(string $string, ?string $encoding = null)
- 引数(表)
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
$string | string | ✓ | なし | 対象の文字列 |
$encoding | ?string | null | 文字エンコーディング。null は mb_internal_encoding() の設定を使用。一般に 'UTF-8' を明示指定推奨 |
- 戻り値:
int— 文字数(コードポイント数) - 例外/副作用:
TypeError(型不一致)ValueError(無効なエンコーディング指定 等)- 必要拡張:
ext-mbstring(任意でgrapheme_*系はext-intl)
使用例
最小例
<?php
declare(strict_types=1);
$text = 'こんにちは'; // 5文字
echo mb_strlen($text, 'UTF-8'); // 5
// バイト数との違い
echo strlen($text); // 15(UTF-8は1文字=3バイト)
実務例(バリデーション:見た目の文字数にも対応)
<?php
declare(strict_types=1);
// ルール: 1〜100文字(見た目の文字数で数えたい場合は grapheme_* を利用)
function lengthValid(string $s, int $min = 1, int $max = 100): bool
{
// 見た目の文字数を優先(ext-intl が無い場合は mb_strlen をフォールバック)
$len = function_exists('grapheme_strlen')
? grapheme_strlen($s)
: mb_strlen($s, 'UTF-8');
return $len >= $min && $len <= $max;
}
// DBの列制限が「バイト数」のときは strlen を使う例(utf8mb4 で 191バイト以内など)
function fitsBytes(string $s, int $maxBytes): bool
{
return strlen($s) <= $maxBytes;
}
// 無効なエンコーディング指定の例外処理
try {
$n = mb_strlen('テスト', 'INVALID-ENCODING'); // ValueError
} catch (ValueError $e) {
error_log('エンコーディング指定が不正: ' . $e->getMessage());
}
よくある落とし穴・注意
- 合成絵文字・ZWJ:
"👨👩👧👦"は見た目1文字でもコードポイントは複数。mb_strlenは 7 を返すことがある。見た目ベースならgrapheme_strlen(ext-intl)。 - バイト数と混同しない:MySQL
VARCHAR(100)にバイト制限が絡む場合はstrlenで確認(UTF-8 は最大4バイト/文字)。 - 内部エンコーディングに依存しない:
mb_internal_encoding()によるグローバル状態は予期せぬバグの元。'UTF-8'を明示指定する。 - 拡張が無効:
Call to undefined function mb_strlen()はext-mbstring未有効。環境によりインストール/有効化が必要。 - 8.1/8.2/8.3 差分:大きな仕様変更なし(8.0 で一部エラーが
ValueErrorに変更済み)。
代替・関連APIとの比較
strlen…… バイト数。プロトコル/DBのサイズ制限チェックに。mb_strlen…… コードポイント数。言語学的な「文字数」カウントに。grapheme_strlen…… ユーザー視点の見た目の文字数(書記素クラスタ)。UI の文字数制限・折返しに最適。mb_strwidth…… 表示幅(全角=2、半角=1 的な幅)。CLI 表や桁揃えに。
テスト例(Pest)
<?php
it('counts multibyte characters', function () {
expect(mb_strlen('あ', 'UTF-8'))->toBe(1);
expect(mb_strlen('🍣', 'UTF-8'))->toBe(1); // 単一コードポイント絵文字
});
it('shows difference for grapheme clusters', function () {
$family = "👨👩👧👦"; // 見た目1文字の家族絵文字
expect(mb_strlen($family, 'UTF-8'))->toBeGreaterThan(1); // 例: 7
if (function_exists('grapheme_strlen')) {
expect(grapheme_strlen($family))->toBe(1);
}
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
Call to undefined function mb_strlen() | ext-mbstring 未有効 | PHP拡張をインストール/有効化(php -m で確認) |
ValueError: mb_strlen(): Argument #2 ($encoding) must be a valid encoding | 無効なエンコーディング名 | 'UTF-8' を明示。mb_list_encodings() で対応一覧を確認 |
| 文字数と見た目が合わない | 合成絵文字・結合記号(ZWJ) | grapheme_strlen を使用(ext-intl が必要) |
| DB保存で桁溢れ | バイト数制限を文字数で判定 | 挿入前に strlen($s) でバイトを確認 |
| 本番でのみ文字化け | 内部エンコーディング差異 | すべて 'UTF-8' 明示 + 入出力経路を統一 |
参考リンク
- PHP 公式マニュアル — mb_strlen
- PHP 公式マニュアル — mbstring 拡張
- PHP 公式マニュアル — grapheme_*(Intl)
- PHP 公式マニュアル — mb_strwidth
- PHP 公式マニュアル — mb_substr

