substr()やstrlen()はバイト数で処理するため、日本語(UTF-8)が文字化けするmb_strimwidth()を使えば、指定した表示幅を超えたときだけ自動で末尾に...を付けて丸められる- 日本語の正確な文字数をカウントするときは、必ず
mb_strlen()を使う
1. 今日のお題とゴール
ブログの記事タイトル一覧を表示するとき、長すぎるタイトルだけ末尾を ... で省略し、横に元の文字数を添えて出力する処理を書いてみましょう。
- 各タイトルの正確な文字数を
mb_strlen()で取得する - 表示幅が半角24文字分(全角12文字分)を超えるタイトルだけ、末尾を
...に丸める - 短いタイトルには
...を付けず、そのまま表示する
// 期待する出力例
PHP入門(全5文字)
PHP8で学ぶWebアプリ開...(全26文字)
HTMLとCSSの基本まとめ(全14文字)
2. ❌ やりがちなNGコード vs ⭕ コピペで動く正解コード
<?php
$title = 'PHP8で学ぶWebアプリ開発!初心者向け実践ガイド';
// バイト数で切り取る substr() は日本語の途中で切れて文字化けする
echo substr($title, 0, 20) . '...';
// 出力: PHP8で学ぶWebア...
// strlen() も文字数ではなくバイト数(64)を返してしまう
echo strlen($title) . '文字'; // 出力: 64文字(実際は26文字)
substr() や strlen() は「文字数」ではなく「バイト数」で処理するため、1文字3バイトの日本語(UTF-8)が途中で切断されて文字化けします。また、末尾に . '...' を直接つなぐと、短いタイトルにまで ... が付いてしまいます。
<?php
declare(strict_types=1);
$titles = [
'PHP入門',
'PHP8で学ぶWebアプリ開発!初心者向け実践ガイド',
'HTMLとCSSの基本まとめ',
];
$maxWidth = 24; // 最大表示幅(半角24文字=全角12文字分)
foreach ($titles as $title) {
// 1. マルチバイト対応で正確な文字数を数える
$length = mb_strlen($title, 'UTF-8');
// 2. 指定幅を超える場合だけ末尾を「...」に丸める
$shortTitle = mb_strimwidth($title, 0, $maxWidth, '...', 'UTF-8');
// 3. 整形したタイトルと元の文字数を出力
echo "{$shortTitle}(全{$length}文字)" . PHP_EOL;
}
3. ここだけ押さえる!3つのポイント
mb_strimwidth($title, 0, 24, '...') は、指定した幅を超えたときだけ末尾を ... に置き換えてくれます。短い文字列には ... が付かないため、面倒な if 文での分岐が不要になります。
mb_strimwidth() は半角英数字を幅1、全角日本語を幅2として計算し、末尾の ...(幅3)を含めて指定幅に収めます。英数字と日本語が混ざる記事タイトルでも、一覧画面で横幅がピタッと揃うのが大きな強みです。
UTF-8の日本語は1文字で3バイトあるため、strlen() を使うと3倍近い数値が返ってしまいます。日本語の文字数を正確に数えるときは、必ずマルチバイト対応の mb_strlen() を使いましょう。
4. 1分ミニチャレンジ
🚀 手を動かしてみよう
正解コードの $maxWidth = 24; の1行を $maxWidth = 14; に変えて実行してみましょう。
ヒント:さきほどはそのまま表示されていた3つ目の『HTMLとCSSの基本まとめ』も、幅14に収まるよう HTMLとCSSの... に自動で丸められます!