【PHP8.x】mb_substr()関数の使い方
mb_substr関数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
mb_substr関数は、指定された文字列から一部を抽出する関数です。この関数は、特に日本語や中国語のようなマルチバイト文字を安全かつ正確に扱うために設計されています。通常のsubstr関数がバイト数に基づいて文字列を切り出すのに対し、mb_substr関数は実際の文字数に基づいて切り出すため、マルチバイト文字を含む文字列を扱う際に発生する文字化けや誤った部分文字列の抽出を防ぐことができます。
第一引数には操作対象となる文字列を、第二引数には抽出を開始する文字の位置を整数で指定します。位置は0から始まります。この開始位置に負の値を指定した場合、文字列の末尾からの相対的な位置として解釈されます。第三引数には抽出する文字の長さを整数で指定します。この長さを省略した場合、開始位置から文字列の最後までが抽出されます。また、長さに負の値を指定すると、文字列の末尾からその文字数分を引いた位置までが抽出されます。第四引数には文字エンコーディングを指定することができ、省略された場合はPHPの内部エンコーディング設定が使用されます。
mb_substr関数は、ウェブアプリケーションでユーザーが入力した長いテキストを要約表示したり、特定の文字数に制限して出力したりする場合など、多バイト文字を含む文字列処理において非常に重要な役割を果たします。これにより、開発者は文字エンコーディングを意識した正確な文字列操作を容易に実現できます。
構文(syntax)
1<?php 2$string = "PHPのマルチバイト文字列"; 3$start = 0; 4$length = 3; 5$encoding = 'UTF-8'; 6$substring = mb_substr($string, $start, $length, $encoding); 7?>
引数(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 を返します。
サンプルコード
PHPでマルチバイト部分文字列の出現回数を数える
1<?php 2 3/** 4 * マルチバイト文字列内で、特定の部分文字列が何回出現するかをカウントします。 5 * mb_substr と同様にマルチバイト文字の処理に対応しています。 6 * 7 * @param string $haystack 検索対象の文字列 8 * @param string $needle 検索する部分文字列 9 * @param ?string $encoding 使用する文字エンコーディング。nullの場合は内部エンコーディングを使用します。 10 * @return int 部分文字列の出現回数 11 */ 12function countMbSubstringOccurrences(string $haystack, string $needle, ?string $encoding = null): int 13{ 14 // 検索する部分文字列が空の場合は、出現回数を0として返します。 15 // 空文字列を検索すると無限にマッチする可能性があるため、明確に0とします。 16 if ($needle === '') { 17 return 0; 18 } 19 20 // エンコーディングが指定されていない場合、PHPの内部エンコーディングを使用します。 21 // mb_substr も同様にエンコーディングを扱います。 22 if ($encoding === null) { 23 $encoding = mb_internal_encoding(); 24 } 25 26 $count = 0; // 部分文字列の出現回数を格納する変数 27 $offset = 0; // 検索を開始する位置のオフセット 28 29 // 検索する部分文字列の文字数を取得します。 30 // mb_strlen を使うことでマルチバイト文字を正しく扱います。 31 $needleLength = mb_strlen($needle, $encoding); 32 33 // 文字列の末尾まで検索を繰り返します。 34 // mb_strpos を使用して、指定された部分文字列が最初に現れる位置を探します。 35 // mb_strpos は mb_substr と同様にマルチバイト文字列を安全に扱います。 36 while (($pos = mb_strpos($haystack, $needle, $offset, $encoding)) !== false) { 37 $count++; // 部分文字列が見つかったらカウントを増やします。 38 // 次の検索は、見つかった部分文字列の直後から開始します。 39 // これにより、重複してカウントされるのを防ぎます。 40 $offset = $pos + $needleLength; 41 } 42 43 return $count; // 最終的な出現回数を返します。 44} 45 46// --- 使用例 --- 47// 実行環境によっては、mb_internal_encoding() を明示的に設定する必要がある場合があります。 48// mb_internal_encoding('UTF-8'); 49 50$text1 = "こんにちは世界、PHPの世界へようこそ。世界は広い。"; 51$searchWord1 = "世界"; 52$occurrences1 = countMbSubstringOccurrences($text1, $searchWord1, 'UTF-8'); 53echo "文字列 '{$text1}' に '{$searchWord1}' は {$occurrences1} 回出現します。\n"; 54 55$text2 = "apple banana apple orange apple"; 56$searchWord2 = "apple"; 57$occurrences2 = countMbSubstringOccurrences($text2, $searchWord2); // エンコーディング省略 (内部エンコーディング使用) 58echo "文字列 '{$text2}' に '{$searchWord2}' は {$occurrences2} 回出現します。\n"; 59 60$text3 = "あいうえおあいうえお"; 61$searchWord3 = "いう"; 62$occurrences3 = countMbSubstringOccurrences($text3, $searchWord3, 'UTF-8'); 63echo "文字列 '{$text3}' に '{$searchWord3}' は {$occurrences3} 回出現します。\n"; 64 65$text4 = "aaaaa"; 66$searchWord4 = "aa"; 67$occurrences4 = countMbSubstringOccurrences($text4, $searchWord4); 68echo "文字列 '{$text4}' に '{$searchWord4}' は {$occurrences4} 回出現します。\n"; // "aa"が重複せず2回カウントされる ("aa"|"aa"|a) 69 70$text5 = "PHPはPHPのプログラミング言語です。"; 71$searchWord5 = "PHP"; 72$occurrences5 = countMbSubstringOccurrences($text5, $searchWord5, 'UTF-8'); 73echo "文字列 '{$text5}' に '{$searchWord5}' は {$occurrences5} 回出現します。\n"; 74 75// 検索文字列が空の場合のテスト 76$occurrencesEmpty = countMbSubstringOccurrences("test", ""); 77echo "文字列 'test' に空文字列は {$occurrencesEmpty} 回出現します。\n"; 78 79// 見つからない場合のテスト 80$occurrencesNotFound = countMbSubstringOccurrences($text1, "Java"); 81echo "文字列 '{$text1}' に 'Java' は {$occurrencesNotFound} 回出現します。\n";
このPHPサンプルコードは、マルチバイト文字列内で特定の部分文字列が何回出現するかをカウントするcountMbSubstringOccurrences関数を定義しています。この関数は、mb_substr関数と同様にマルチバイト文字の処理に対応しており、日本語のような複雑な文字列でも正確に扱うことができます。
引数として、検索対象の文字列である$haystack、検索したい部分文字列である$needle、そしてオプションで文字エンコーディングを指定する$encodingを受け取ります。$encodingが省略された場合は、PHPの内部エンコーディングが自動的に使用されます。特に、$needleが空文字列の場合は、意図しない無限マッチを避けるため、出現回数は0として処理されます。
関数内部では、mb_strpos関数で部分文字列の出現位置を探し、mb_strlen関数で部分文字列の長さを正確に取得しながら、whileループを使って文字列の末尾まで検索を繰り返します。一度見つかった部分文字列の直後から次の検索を開始することで、重複なく出現回数を数え上げ、最終的にその合計を整数値で返します。これにより、マルチバイト文字列の複雑なテキスト解析を簡単に行うことができます。
このサンプルコードは、mb_プレフィックスが付くPHPの関数群(mb_strpos、mb_strlenなど)を利用し、日本語のようなマルチバイト文字を含む文字列を正確に処理します。最も重要な点は、文字エンコーディングを正しく扱うことです。引数でencodingを明示的に指定しない場合、PHPの内部エンコーディングが使用されるため、環境によっては意図しない結果になることがあります。特に異なる言語の文字を扱う際は、常にUTF-8などを指定することを推奨します。また、検索する部分文字列が空の場合、無限ループや予期せぬ結果を防ぐために、出現回数を0として返しています。この関数は、重複しない形で部分文字列の出現回数を正確にカウントします。これらの点に注意し、安全にご利用ください。
mb_substrで部分文字列を安全に取得する
1<?php 2 3/** 4 * マルチバイト文字列から安全に部分文字列を取得するデモンストレーション関数です。 5 * mbstring 拡張が有効でない場合の対応や、基本的な使用方法を含みます。 6 * 7 * @param string $text 元の文字列。 8 * @param int $start 取得を開始する文字位置。0から始まります。 9 * @param int|null $length 取得する文字数。null の場合、開始位置から文字列の最後まで取得します。 10 * @param string|null $encoding 使用する文字エンコーディング。null の場合、mb_internal_encoding() で設定された 11 * 内部エンコーディングが使用されます。明示的に'UTF-8'などを指定することが推奨されます。 12 * @return string 部分文字列、またはエラーメッセージ。 13 */ 14function safeMbSubstr(string $text, int $start, ?int $length = null, ?string $encoding = null): string 15{ 16 // PHP mbstring 拡張がロードされているか確認します。 17 // もしロードされていない場合、mb_substr 関数は利用できません。 18 // php.ini で 'extension=mbstring' を有効にする必要があります。 19 if (!function_exists('mb_substr')) { 20 return "エラー: mbstring 拡張がPHPにロードされていません。php.ini を確認してください。"; 21 } 22 23 // マルチバイト文字列を安全に扱うために、内部エンコーディングを正しく設定することが推奨されます。 24 // 特に、入力文字列のエンコーディングが不明な場合や、異なるエンコーディングの文字列を扱う場合に重要です。 25 // ここでは、一時的に内部エンコーディングを 'UTF-8' に設定し、処理後に元に戻します。 26 $originalInternalEncoding = mb_internal_encoding(); 27 if ($encoding === null) { 28 // mb_substr の $encoding 引数が指定されていない場合、内部エンコーディングが使用されるため、 29 // ここで安全なデフォルト値(UTF-8)に設定します。 30 mb_internal_encoding('UTF-8'); 31 } 32 33 // mb_substr を呼び出します。 34 // 戻り値は string またはエラー時に false です。 35 $result = mb_substr($text, $start, $length, $encoding); 36 37 // 内部エンコーディングを元の設定に戻します(もし変更した場合)。 38 if ($encoding === null) { 39 mb_internal_encoding($originalInternalEncoding); 40 } 41 42 if ($result === false) { 43 // mb_substr は内部エラー(例: 無効なエンコーディング指定)の場合に false を返すことがあります。 44 return "エラー: mb_substr の実行中に問題が発生しました。引数を確認してください。"; 45 } 46 47 return $result; 48} 49 50// -------------------------------------------------------------------------- 51// サンプル使用例 52// -------------------------------------------------------------------------- 53 54// 1. 基本的な使用例(日本語文字列) 55$japaneseString = "こんにちは世界、これはPHPのテストです。"; 56echo "元の文字列: " . $japaneseString . PHP_EOL; 57echo "最初の5文字: " . safeMbSubstr($japaneseString, 0, 5) . PHP_EOL; // 出力: こんにちは世界 58 59// 2. 開始位置と長さを指定 60echo "開始位置3から4文字: " . safeMbSubstr($japaneseString, 3, 4) . PHP_EOL; // 出力: にちは世 61 62// 3. 長さを指定しない場合(開始位置から最後まで) 63echo "開始位置7から最後まで: " . safeMbSubstr($japaneseString, 7) . PHP_EOL; // 出力: 界、これはPHPのテストです。 64 65// 4. 文字列の長さを超える開始位置を指定した場合(空文字列が返されます) 66echo "開始位置が大きすぎる場合: " . safeMbSubstr($japaneseString, 100) . PHP_EOL; // 出力: (空行) 67 68// 5. エンコーディングを明示的に指定する例 69// (この例では入力がUTF-8なので、指定しなくても同じ結果になりますが、 70// 異なるエンコーディングの文字列を扱う場合には重要です。) 71$utf8String = "PHPサンプル"; 72echo "エンコーディング指定あり: " . safeMbSubstr($utf8String, 0, 3, 'UTF-8') . PHP_EOL; // 出力: PHP 73 74// 6. mbstring 拡張が有効でない場合のメッセージの例 75// 実際には、このスクリプトを実行している環境でmbstring拡張が有効であれば、 76// 以下のメッセージは表示されず、「mbstring 拡張は有効です。」と表示されます。 77// もし本当にmbstring拡張が無効な環境で実行されると、最初のエラーメッセージが出力されます。 78echo PHP_EOL . "--- mbstring拡張が有効でない場合のメッセージのシミュレーション ---" . PHP_EOL; 79if (!function_exists('mb_substr')) { 80 echo safeMbSubstr("テスト", 0, 1) . PHP_EOL; 81} else { 82 echo "mbstring 拡張は有効です。上記のエラーメッセージは表示されません。" . PHP_EOL; 83}
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.iniでextension=mbstringを有効にし、mbstring拡張をPHPにロードする必要があります。文字化けや誤った結果を防ぐため、引数$encodingでエンコーディングを明示的に指定するか、mb_internal_encoding()で内部エンコーディングを正しく設定することが非常に重要です。関数が実行に失敗した場合、戻り値はfalseとなるため、必ず結果を確認しエラー処理を実装してください。引数$lengthを省略すると、開始位置から文字列の最後までが取得されます。
PHP mb_substr で文字列を後ろから切り出す
1<?php 2 3/** 4 * マルチバイト文字列の末尾から指定された文字数だけ文字列を切り出します。 5 * 6 * @param string $string 元の文字列。 7 * @param int $length 末尾から切り出す文字数。この値が負の場合、mb_substrは空文字列を返します。 8 * また、元の文字列の文字数より大きい場合、元の文字列全体が返されます。 9 * @param string $encoding 文字列のエンコーディング。デフォルトは 'UTF-8'。 10 * @return string|false 切り出された部分文字列、またはエラーが発生した場合は false。 11 */ 12function get_suffix(string $string, int $length, string $encoding = 'UTF-8'): string|false 13{ 14 // mb_substr の第二引数に負の値を指定すると、文字列の末尾からのオフセットになります。 15 // 例えば、-5 は末尾から5文字目の位置を指します。 16 // 第三引数には切り出す文字数を指定することで、その位置から指定された文字数だけ切り出します。 17 return mb_substr($string, -$length, $length, $encoding); 18} 19 20// --- サンプルコードの実行 --- 21 22// 日本語を含むマルチバイト文字列 23$text = "PHPは素晴らしいプログラミング言語です。"; 24$encoding = 'UTF-8'; 25 26echo "元の文字列: " . $text . PHP_EOL; 27echo "エンコーディング: " . $encoding . PHP_EOL . PHP_EOL; 28 29// 例1: 末尾から5文字を切り出す 30$suffix1 = get_suffix($text, 5, $encoding); 31if ($suffix1 !== false) { 32 echo "末尾から5文字: " . $suffix1 . PHP_EOL; // 出力: 言語です。 33} else { 34 echo "エラー: 末尾からの切り出しに失敗しました。" . PHP_EOL; 35} 36 37// 例2: 末尾から10文字を切り出す 38$suffix2 = get_suffix($text, 10, $encoding); 39if ($suffix2 !== false) { 40 echo "末尾から10文字: " . $suffix2 . PHP_EOL; // 出力: プログラミング言語です。 41} else { 42 echo "エラー: 末尾からの切り出しに失敗しました。" . PHP_EOL; 43} 44 45// 例3: 切り出す文字数が元の文字列の長さより長い場合 46// この場合、mb_substr は元の文字列全体を返します。 47$suffix_long = get_suffix($text, 99, $encoding); 48if ($suffix_long !== false) { 49 echo "末尾から99文字 (元の文字列より長い): " . $suffix_long . PHP_EOL; // 出力: PHPは素晴らしいプログラミング言語です。 50} else { 51 echo "エラー: 末尾からの切り出しに失敗しました。" . PHP_EOL; 52} 53 54// 例4: 切り出す文字数に負の値を指定した場合 55// この場合、mb_substr は空文字列を返します。 56$suffix_negative = get_suffix($text, -3, $encoding); 57if ($suffix_negative !== false) { 58 echo "末尾から-3文字 (負の長さ): '" . $suffix_negative . "'" . PHP_EOL; // 出力: '' (空文字列) 59} else { 60 echo "エラー: 末尾からの切り出しに失敗しました。" . PHP_EOL; 61} 62 63?>
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でないか確認し、適切なエラーハンドリングを行うようにしてください。
PHP mb_substrで文字数指定して部分文字列を切り出す
1<?php 2 3/** 4 * PHP mb_substr関数の基本的な使用例。 5 * マルチバイト文字列から指定した文字数だけ部分文字列を切り出します。 6 * システムエンジニアを目指す初心者向けに、日本語文字列での動作を示します。 7 */ 8 9// 対象となる日本語文字列を定義します。 10$originalString = "プログラミング言語PHPの学習を始めましょう!"; 11echo "元の文字列: " . $originalString . "\n"; 12echo "元の文字列の文字数: " . mb_strlen($originalString, 'UTF-8') . "文字\n\n"; 13 14// mb_substr関数を使用して、部分文字列を切り出します。 15// 引数: 16// 1. $string: 対象の文字列 17// 2. $start: 切り出しを開始する文字の位置 (0から始まる) 18// 3. $length: 切り出す文字数 (省略すると、$startから文字列の最後まで) 19// 4. $encoding: 文字エンコーディング (省略可能ですが、マルチバイト文字を扱う場合は明示的に指定することを強く推奨) 20$startPosition = 5; // 6番目の文字 (「グ」) から切り出しを開始 21$lengthToExtract = 7; // 7文字を切り出す 22 23// 'UTF-8' エンコーディングで、指定した位置から指定した文字数分を切り出します。 24$subString = mb_substr($originalString, $startPosition, $lengthToExtract, 'UTF-8'); 25 26// 切り出した部分文字列を出力します。 27echo "開始位置 " . $startPosition . " から " . $lengthToExtract . " 文字切り出した結果:\n"; 28echo "結果: " . $subString . "\n"; // 期待される出力: グ言語PHPの学習 29 30// 切り出した部分文字列の文字数も確認できます。 31echo "切り出した部分文字列の文字数: " . mb_strlen($subString, 'UTF-8') . "文字\n"; 32 33// mb_substr関数が失敗した場合、falseを返します。 34// 通常、このシンプルな例では発生しませんが、引数の不備などで起こり得ます。 35if ($subString === false) { 36 echo "\nエラー: mb_substr関数が失敗しました。\n"; 37} 38 39?>
PHPのmb_substr関数は、日本語のようなマルチバイト文字列から、指定した範囲で部分文字列を安全に切り出すために使用される重要な関数です。PHP 8の環境で、特にWebアプリケーションなどで日本語を扱う際に、文字化けを起こさずに正確な文字数で文字列操作を行う必要がある場面で活躍します。
この関数は、最初の引数$stringに対象の文字列を受け取ります。次に、$start引数で切り出しを開始する文字の位置を0から数えて指定します。例えば、5を指定すると文字列の6番目の文字から切り出しが始まります。オプションの$length引数で切り出す文字数を指定し、これを省略すると$start位置から文字列の最後までが切り出されます。さらに、$encoding引数で文字エンコーディング(例: 'UTF-8')を指定することで、マルチバイト文字を正しく処理できるようになります。この指定は特に推奨されます。
サンプルコードでは、「プログラミング言語PHPの学習を始めましょう!」という文字列から、開始位置5(「グ」の文字)から7文字を切り出しています。これにより、「グ言語PHPの学習」という部分文字列が正しく取得されます。mb_substr関数は、成功すると指定された部分文字列を文字列として返し、何らかの問題で失敗した場合にはfalseを返します。このように、mb_substr関数はマルチバイト文字列を扱うプログラミングにおいて、文字列の切り出しを正確かつ安全に行うための不可欠なツールです。
このサンプルコードを利用する際の注意点として、日本語などのマルチバイト文字を扱う場合は、通常のsubstr関数ではなく、必ずmb_substr関数を使用してください。substrはバイト数で文字列を切り出すため、文字化けや意図しない結果につながります。また、mb_substr関数のencoding引数には、常に'UTF-8'のように使用している文字エンコーディングを明示的に指定することを強く推奨します。これを省略すると、PHPの内部エンコーディング設定に依存してしまい、予期せぬ動作や環境による違いが生じる可能性があります。start引数は0から数える文字位置ですので、数え間違いに注意してください。関数が文字列の切り出しに失敗した場合はfalseを返すため、結果がfalseでないかを確認する習慣をつけると、より安全なコードになります。