【PHP】文字列の末尾・最後のN文字を取得する方法|substr・mb_substr・文字列オフセット完全解説
PHPで文字列の最後の1文字や末尾のN文字を取得したいとき、substr($str, -1) が最も手軽な方法ですが、日本語などのマルチバイト文字が含まれる場合は注意が必要です。
「substr と mb_substr の違いがわからない」
「文字列オフセット($str[-1])はいつ使える?」
「最後の複数文字を切り出すには?」
この記事では、用途別の取得方法を具体的なコード例とともに解説します。
1. 結論:用途別の早見表
$str = 'Hello World';
// 最後の1文字
$str[-1]; // 'd'(PHP 7.1以降)
substr($str, -1); // 'd'
mb_substr($str, -1); // 'd'(マルチバイト対応)
// 最後のN文字
substr($str, -5); // 'World'
mb_substr($str, -5); // 'World'(マルチバイト対応)
| 方法 | マルチバイト対応 | PHP バージョン | 推奨度 |
|---|---|---|---|
$str[-1] | ❌ | 7.1以降 | ✅ シンプルなASCII文字列 |
substr($str, -1) | ❌ | 全バージョン | ✅ ASCII文字列 |
mb_substr($str, -1) | ✅ | 全バージョン | ✅ 日本語を含む場合 |
2. 文字列オフセットで直接アクセスする(PHP 7.1以降)
PHP 7.1以降では負のオフセットが使えるため、最後の1文字を最も簡潔に取得できます。
$str = 'Hello World';
echo $str[-1]; // 'd'
echo $str[-2]; // 'l'
echo $str[-5]; // 'W'
注意点
$str = 'こんにちは';
echo $str[-1]; // 文字化けする(マルチバイト非対応)
日本語などのマルチバイト文字には使えません。ASCII文字列専用の方法です。
3. substr()で末尾のN文字を取得する
substr() は第2引数に負の値を渡すことで末尾からの位置を指定できます。
$str = 'Hello World';
// 最後の1文字
echo substr($str, -1); // 'd'
// 最後の5文字
echo substr($str, -5); // 'World'
// 最後から2番目の1文字
echo substr($str, -2, 1); // 'l'
第3引数(長さ)の指定
// substr($str, 開始位置, 取得文字数)
echo substr($str, -5, 3); // 'Wor'(末尾5文字目から3文字)
注意点
$str = 'こんにちは';
echo substr($str, -1); // 文字化けする(バイト単位の処理のため)
substr() もマルチバイト文字には対応していません。
4. mb_substr()で日本語を含む文字列に対応する
日本語・中国語・韓国語などのマルチバイト文字を含む場合は必ず mb_substr() を使います。
$str = 'こんにちは';
// 最後の1文字
echo mb_substr($str, -1); // 'は'
// 最後の3文字
echo mb_substr($str, -3); // 'にちは'
// 最後から2番目の1文字
echo mb_substr($str, -2, 1); // 'ち'
英数字と日本語が混在する場合も安全
$str = 'PHPで開発する';
echo mb_substr($str, -1); // 'る'
echo mb_substr($str, -3); // '発する'
実務では mb_substr() を基本にする
30年のPHP実務の経験から言うと、入力値に日本語が含まれる可能性があるフォームやAPIでは、最初から mb_substr() を使っておくのが無難です。substr() で動いていたコードが日本語入力で突然文字化けするトラブルは珍しくありません。
5. 実務での使用シーン
末尾の文字を判定する
// URLが「/」で終わっているか確認
$url = 'https://example.com/';
if (mb_substr($url, -1) === '/') {
echo 'スラッシュで終わっています';
}
// より簡潔にはstr_ends_with()を使う(PHP 8.0以降)
if (str_ends_with($url, '/')) {
echo 'スラッシュで終わっています';
}
ファイル拡張子の取得
// 末尾3文字で拡張子を判定(簡易版)
$filename = 'image.png';
$ext = substr($filename, -3); // 'png'
// より確実にはpathinfo()を使う
$ext = pathinfo($filename, PATHINFO_EXTENSION); // 'png'
文字列の末尾をトリムする
// 末尾の特定文字を削除
$str = '2026年4月';
if (mb_substr($str, -1) === '月') {
$str = mb_substr($str, 0, -1); // '2026年4月' → '2026年4'
}
6. PHP 8.0以降のstr_ends_with()との使い分け
「末尾の文字が特定の文字かどうか判定したい」だけなら、PHP 8.0以降では str_ends_with() が最も明確です。
$str = 'Hello World';
// PHP 8.0以降(推奨)
str_ends_with($str, 'd'); // true
str_ends_with($str, 'World'); // true
// 従来の方法
substr($str, -1) === 'd'; // true
substr($str, -5) === 'World'; // true
マルチバイト版はないため、日本語で判定する場合は mb_substr() を使います。
$str = 'こんにちは';
mb_substr($str, -1) === 'は'; // true
まとめ
| やりたいこと | 推奨する方法 |
|---|---|
| ASCII文字列の最後の1文字 | $str[-1] または substr($str, -1) |
| 日本語を含む最後の1文字 | mb_substr($str, -1) |
| 末尾N文字を取得 | mb_substr($str, -N) |
| 末尾が特定文字か判定(PHP 8.0以降) | str_ends_with($str, '文字') |
| ファイル拡張子の取得 | pathinfo($filename, PATHINFO_EXTENSION) |
迷ったら mb_substr() を使っておけば、日本語が含まれても問題なく動作します。


