【PHP8.x】mb_substr関数の使い方

作成日: 更新日:

mb_substr関数は、指定された文字列から一部を抽出する関数です。この関数は、特に日本語や中国語のようなマルチバイト文字を安全かつ正確に扱うために設計されています。通常のsubstr関数がバイト数に基づいて文字列を切り出すのに対し、mb_substr関数は実際の文字数に基づいて切り出すため、マルチバイト文字を含む文字列を扱う際に発生する文字化けや誤った部分文字列の抽出を防ぐことができます。

第一引数には操作対象となる文字列を、第二引数には抽出を開始する文字の位置を整数で指定します。位置は0から始まります。この開始位置に負の値を指定した場合、文字列の末尾からの相対的な位置として解釈されます。第三引数には抽出する文字の長さを整数で指定します。この長さを省略した場合、開始位置から文字列の最後までが抽出されます。また、長さに負の値を指定すると、文字列の末尾からその文字数分を引いた位置までが抽出されます。第四引数には文字エンコーディングを指定することができ、省略された場合はPHPの内部エンコーディング設定が使用されます。

mb_substr関数は、ウェブアプリケーションでユーザーが入力した長いテキストを要約表示したり、特定の文字数に制限して出力したりする場合など、多バイト文字を含む文字列処理において非常に重要な役割を果たします。これにより、開発者は文字エンコーディングを意識した正確な文字列操作を容易に実現できます。

基本的な使い方

構文(syntax)

<?php
$string = "PHPのマルチバイト文字列";
$start = 0;
$length = 3;
$encoding = 'UTF-8';
$substring = mb_substr($string, $start, $length, $encoding);
?>

引数(parameters)

string $string, int $start, ?int $length = null, ?string $encoding = null

  • string $string: 部分文字列を抽出したい元の文字列
  • int $start: 部分文字列の開始位置を指定する整数(0から始まります)
  • ?int $length = null: 抽出する部分文字列の長さを指定する整数。省略した場合(null)、開始位置から文字列の最後までが抽出されます。
  • ?string $encoding = null: 文字列のエンコーディングを指定する文字列。省略した場合、内部エンコーディングが使用されます。

戻り値(return)

string|false

指定された文字位置から指定された長さの文字列を返します。失敗した場合は false を返します。

サンプルコード

mb_substrで部分文字列を安全に取得する

<?php

/**
 * マルチバイト文字列から安全に部分文字列を取得するデモンストレーション関数です。
 * mbstring 拡張が有効でない場合の対応や、基本的な使用方法を含みます。
 *
 * @param string $text 元の文字列。
 * @param int $start 取得を開始する文字位置。0から始まります。
 * @param int|null $length 取得する文字数。null の場合、開始位置から文字列の最後まで取得します。
 * @param string|null $encoding 使用する文字エンコーディング。null の場合、mb_internal_encoding() で設定された
 *                               内部エンコーディングが使用されます。明示的に'UTF-8'などを指定することが推奨されます。
 * @return string 部分文字列、またはエラーメッセージ。
 */
function safeMbSubstr(string $text, int $start, ?int $length = null, ?string $encoding = null): string
{
    // PHP mbstring 拡張がロードされているか確認します。
    // もしロードされていない場合、mb_substr 関数は利用できません。
    // php.ini で 'extension=mbstring' を有効にする必要があります。
    if (!function_exists('mb_substr')) {
        return "エラー: mbstring 拡張がPHPにロードされていません。php.ini を確認してください。";
    }

    // マルチバイト文字列を安全に扱うために、内部エンコーディングを正しく設定することが推奨されます。
    // 特に、入力文字列のエンコーディングが不明な場合や、異なるエンコーディングの文字列を扱う場合に重要です。
    // ここでは、一時的に内部エンコーディングを 'UTF-8' に設定し、処理後に元に戻します。
    $originalInternalEncoding = mb_internal_encoding();
    if ($encoding === null) {
        // mb_substr の $encoding 引数が指定されていない場合、内部エンコーディングが使用されるため、
        // ここで安全なデフォルト値(UTF-8)に設定します。
        mb_internal_encoding('UTF-8');
    }

    // mb_substr を呼び出します。
    // 戻り値は string またはエラー時に false です。
    $result = mb_substr($text, $start, $length, $encoding);

    // 内部エンコーディングを元の設定に戻します(もし変更した場合)。
    if ($encoding === null) {
        mb_internal_encoding($originalInternalEncoding);
    }

    if ($result === false) {
        // mb_substr は内部エラー(例: 無効なエンコーディング指定)の場合に false を返すことがあります。
        return "エラー: mb_substr の実行中に問題が発生しました。引数を確認してください。";
    }

    return $result;
}

// --------------------------------------------------------------------------
// サンプル使用例
// --------------------------------------------------------------------------

// 1. 基本的な使用例(日本語文字列)
$japaneseString = "こんにちは世界、これはPHPのテストです。";
echo "元の文字列: " . $japaneseString . PHP_EOL;
echo "最初の5文字: " . safeMbSubstr($japaneseString, 0, 5) . PHP_EOL; // 出力: こんにちは世界

// 2. 開始位置と長さを指定
echo "開始位置3から4文字: " . safeMbSubstr($japaneseString, 3, 4) . PHP_EOL; // 出力: にちは世

// 3. 長さを指定しない場合(開始位置から最後まで)
echo "開始位置7から最後まで: " . safeMbSubstr($japaneseString, 7) . PHP_EOL; // 出力: 界、これはPHPのテストです。

// 4. 文字列の長さを超える開始位置を指定した場合(空文字列が返されます)
echo "開始位置が大きすぎる場合: " . safeMbSubstr($japaneseString, 100) . PHP_EOL; // 出力: (空行)

// 5. エンコーディングを明示的に指定する例
// (この例では入力がUTF-8なので、指定しなくても同じ結果になりますが、
// 異なるエンコーディングの文字列を扱う場合には重要です。)
$utf8String = "PHPサンプル";
echo "エンコーディング指定あり: " . safeMbSubstr($utf8String, 0, 3, 'UTF-8') . PHP_EOL; // 出力: PHP

// 6. mbstring 拡張が有効でない場合のメッセージの例
// 実際には、このスクリプトを実行している環境でmbstring拡張が有効であれば、
// 以下のメッセージは表示されず、「mbstring 拡張は有効です。」と表示されます。
// もし本当にmbstring拡張が無効な環境で実行されると、最初のエラーメッセージが出力されます。
echo PHP_EOL . "--- mbstring拡張が有効でない場合のメッセージのシミュレーション ---" . PHP_EOL;
if (!function_exists('mb_substr')) {
    echo safeMbSubstr("テスト", 0, 1) . PHP_EOL;
} else {
    echo "mbstring 拡張は有効です。上記のエラーメッセージは表示されません。" . PHP_EOL;
}

PHPのmb_substr関数は、日本語のようなマルチバイト文字を安全に扱うための重要な関数です。一般的なsubstr関数では、文字の途中で切り取られて文字化けすることがありますが、mb_substrは指定されたエンコーディングに基づいて正しく文字単位で文字列を切り取ります。

このサンプルコードでは、mb_substr関数をより安全に利用するためのsafeMbSubstrという関数を定義しています。まず、mbstring拡張機能がPHPにロードされているかを確認し、もしロードされていない場合はエラーメッセージを返します。これにより、「mb_substrが使えない」状況に対応しています。

次に、マルチバイト文字列の処理ではエンコーディングの指定が重要となるため、mb_internal_encoding関数を使って一時的に内部エンコーディングを設定し、処理後に元の設定に戻すことで、予期せぬ文字化けを防ぐ工夫がされています。

mb_substr関数には、元の文字列($string)、取得を開始する文字位置($start)、取得する文字数($length)、そして使用する文字エンコーディング($encoding)を引数として渡します。$startは0から数え、$lengthを省略した場合は開始位置から文字列の最後までを取得します。戻り値は切り取られた文字列ですが、内部的なエラーが発生した場合にはfalseを返します。サンプルコードでは、これらの戻り値も適切に処理しています。

コードの後半では、具体的な日本語文字列での部分取得や、開始位置と長さの指定、エンコーディングの明示的な指定など、様々な使用例が示されており、mb_substr関数がどのように機能するのか、実践的な動作を確認することができます。

mb_substr関数は、日本語などのマルチバイト文字を正確に部分文字列として取得するために利用されます。この関数を使用するには、php.iniextension=mbstringを有効にし、mbstring拡張をPHPにロードする必要があります。文字化けや誤った結果を防ぐため、引数$encodingでエンコーディングを明示的に指定するか、mb_internal_encoding()で内部エンコーディングを正しく設定することが非常に重要です。関数が実行に失敗した場合、戻り値はfalseとなるため、必ず結果を確認しエラー処理を実装してください。引数$lengthを省略すると、開始位置から文字列の最後までが取得されます。

PHP mb_substr で文字列を後ろから切り出す

<?php

/**
 * マルチバイト文字列の末尾から指定された文字数だけ文字列を切り出します。
 *
 * @param string $string 元の文字列。
 * @param int $length 末尾から切り出す文字数。この値が負の場合、mb_substrは空文字列を返します。
 *                      また、元の文字列の文字数より大きい場合、元の文字列全体が返されます。
 * @param string $encoding 文字列のエンコーディング。デフォルトは 'UTF-8'。
 * @return string|false 切り出された部分文字列、またはエラーが発生した場合は false。
 */
function get_suffix(string $string, int $length, string $encoding = 'UTF-8'): string|false
{
    // mb_substr の第二引数に負の値を指定すると、文字列の末尾からのオフセットになります。
    // 例えば、-5 は末尾から5文字目の位置を指します。
    // 第三引数には切り出す文字数を指定することで、その位置から指定された文字数だけ切り出します。
    return mb_substr($string, -$length, $length, $encoding);
}

// --- サンプルコードの実行 ---

// 日本語を含むマルチバイト文字列
$text = "PHPは素晴らしいプログラミング言語です。";
$encoding = 'UTF-8';

echo "元の文字列: " . $text . PHP_EOL;
echo "エンコーディング: " . $encoding . PHP_EOL . PHP_EOL;

// 例1: 末尾から5文字を切り出す
$suffix1 = get_suffix($text, 5, $encoding);
if ($suffix1 !== false) {
    echo "末尾から5文字: " . $suffix1 . PHP_EOL; // 出力: 言語です。
} else {
    echo "エラー: 末尾からの切り出しに失敗しました。" . PHP_EOL;
}

// 例2: 末尾から10文字を切り出す
$suffix2 = get_suffix($text, 10, $encoding);
if ($suffix2 !== false) {
    echo "末尾から10文字: " . $suffix2 . PHP_EOL; // 出力: プログラミング言語です。
} else {
    echo "エラー: 末尾からの切り出しに失敗しました。" . PHP_EOL;
}

// 例3: 切り出す文字数が元の文字列の長さより長い場合
// この場合、mb_substr は元の文字列全体を返します。
$suffix_long = get_suffix($text, 99, $encoding);
if ($suffix_long !== false) {
    echo "末尾から99文字 (元の文字列より長い): " . $suffix_long . PHP_EOL; // 出力: PHPは素晴らしいプログラミング言語です。
} else {
    echo "エラー: 末尾からの切り出しに失敗しました。" . PHP_EOL;
}

// 例4: 切り出す文字数に負の値を指定した場合
// この場合、mb_substr は空文字列を返します。
$suffix_negative = get_suffix($text, -3, $encoding);
if ($suffix_negative !== false) {
    echo "末尾から-3文字 (負の長さ): '" . $suffix_negative . "'" . PHP_EOL; // 出力: '' (空文字列)
} else {
    echo "エラー: 末尾からの切り出しに失敗しました。" . PHP_EOL;
}

?>

PHPのmb_substr関数は、日本語のようなマルチバイト文字を含む文字列から、指定された部分を安全に切り出すための重要な関数です。このサンプルコードでは、mb_substr関数を応用し、文字列の「末尾から」特定の文字数だけを切り出すための独自関数get_suffixを定義しています。

get_suffix関数は、元の文字列($string)、末尾から切り出す文字数($length)、および文字列のエンコーディング($encoding、デフォルトは'UTF-8')を引数として受け取ります。戻り値は切り出された部分文字列、またはエラーが発生した場合はfalseです。

この関数内でmb_substrを呼び出す際、第二引数である開始位置($start)に負の値、具体的には-$lengthを指定しています。mb_substrでは、開始位置に負の値を指定すると、文字列の末尾からのオフセットとして解釈されます。例えば、-5と指定すると末尾から5文字目の位置を意味します。そして、第三引数にも切り出す文字数である$lengthを指定することで、末尾からの指定位置から、その文字数だけを正確に切り出すことが可能になります。

サンプルコードの実行例では、"PHPは素晴らしいプログラミング言語です。"という文字列を対象に、末尾から5文字や10文字を切り出す基本的な動作を示しています。また、切り出す文字数$lengthが元の文字列の文字数より長い場合には文字列全体が返されること、$lengthに負の値を指定すると空文字列が返されるといったmb_substrの特殊な挙動も確認できます。このようにmb_substrを利用することで、マルチバイト文字を含む文字列でも文字化けを心配することなく、正確な文字列操作が行えます。

このサンプルコードは、mb_substr関数を用いてマルチバイト文字列の末尾から文字を切り出す方法を示しています。mb_substrは、日本語などのマルチバイト文字を正確に処理するために非常に重要であり、通常のsubstrでは文字化けが発生する可能性があります。

特に注意すべき点は、mb_substrの第二引数(開始位置)に負の値を指定すると、文字列の末尾からのオフセットとして機能する点です。サンプルコードではこの特性を利用して末尾から切り出しています。また、第三引数(切り出す文字数)が負の値の場合、mb_substrは空文字列を返しますので、意図しない挙動にならないよう注意が必要です。元の文字列の長さを超える文字数を指定した場合は、元の文字列全体が返されます。

文字化けを防ぐため、第四引数でエンコーディング(例: 'UTF-8')を明示的に指定することを強く推奨します。mb_substrは処理に失敗した場合falseを返すため、安全に利用するためには必ず戻り値がfalseでないか確認し、適切なエラーハンドリングを行うようにしてください。

【PHP8.x】mb_substr関数の使い方 | いっしー@Webエンジニア