【PHP実践|実務向け】PHP 7.2から使える「mb_scrub」で不正なマルチバイト文字列を安全に処理する方法

1. 導入

Web開発において、外部から送られてくるデータ(フォーム入力、APIリクエスト、外部CSVなど)には、予期せぬ文字化けや、エンコーディング仕様に合致しない「不正なバイトシーケンス」が含まれることがあります。これらをそのままデータベースへ保存したり、処理しようとすると、例外が発生したり、システムが予期せぬ動作をしたりするリスクがあります。PHP 7.2で導入されたmb_scrub関数は、そうした「不正なバイト」を安全な代替文字(置換文字)に置き換えることで、プログラムの堅牢性を高める非常に便利なツールです。

2. 基礎知識

マルチバイト文字列(UTF-8など)では、特定のバイトパターンが文字として定義されています。しかし、通信途中のデータ欠損や不正なエンコード処理により、定義外のバイト列が混入することがあります。
これまで、こうした不正なバイト列を取り除くには、一度別のエンコーディングに変換してから戻すといった「ハック」が必要でした。mb_scrubは、「自分自身のエンコーディングで再変換する」という処理を行うことで、不正な箇所だけを検出して置換する専用の関数です。

3. 実装/解決策

mb_scrubは非常にシンプルで、対象の文字列とエンコーディングを指定するだけです。
基本的には対象文字列を第一引数に渡すだけで、現在の内部エンコーディング設定に基づいて処理が行われます。もし明示的にUTF-8として処理したい場合は、第二引数にエンコーディングを指定してください。不正なバイト列は見つかった場合、PHPの標準的な置換文字(通常は「?」)に置き換えられます。

4. サンプルプログラム

以下は、不正なバイトシーケンスを含む可能性のある文字列をクリーンアップする実用的なコード例です。

  • 不正なバイトシーケンスを含む可能性のある文字列を浄化する関数
  • /
    function sanitizeInput(string $input): string
    {
    // UTF-8として不正なバイト列を置換する
    // mb_scrubは指定されたエンコーディングで再エンコードすることで
    // 不正なバイト列を検出し、自動的に置換文字に置き換えます
    $cleaned = mb_scrub($input, ‘UTF-8’);

    return $cleaned;
    }

    // サンプル: 途中で途切れたUTF-8文字(不正なバイト)を含む文字列
    // ※以下の文字列は便宜上の例です
    $dirtyString = “正常な文字列” . “\xFF” . “あいうえお”;

    $result = sanitizeInput($dirtyString);

    echo “元データ: ” . bin2hex($dirtyString) . PHP_EOL;
    echo “浄化後: ” . $result . PHP_EOL;
    // 浄化後は \xFF の部分が置換文字に置き換わります
    ?>

    5. 応用・注意点

    実務における注意点は以下の通りです。

    ・パフォーマンスへの考慮:
    大量の文字列をループ内で処理する場合、mb_scrubの呼び出しはオーバーヘッドになります。必要な箇所(外部からの入力直後など)でのみ実行するようにしましょう。
    ・文字化けの根本解決ではない:
    mb_scrubは「不正なバイトを消す(置換する)」ものであり、文字コードの誤変換(Shift-JISをUTF-8と誤認識しているなど)を直すものではありません。文字コードの判定にはmb_detect_encodingなどを併用してください。
    ・置換文字の確認:
    環境や設定によっては置換文字が期待と異なる場合があります。出力先がHTMLであれば、適切にHTMLエンティティ化されているかどうかも併せて確認することが、セキュリティ上のベストプラクティスです。

    タイトルとURLをコピーしました