文字エンコーディングを検出する

# mb_detect_encoding

(PHP 4 >= 4.0.6, PHP 5, PHP 7, PHP 8)

mb_detect_encoding — 文字エンコーディングを検出する

### 説明

function mb_detect_encoding(string `$string`, array|string|null `$encodings` = `null`, bool `$strict` = `false`): string|false

エンコーディングの候補の一覧から、 文字列 `string` のもっとも可能性が高い文字エンコーディングを検出します。

PHP 8.1 以降では、 この関数は指定されたテキスト中の有効なテキストエンコーディングのうち、 もっとも正しい可能性が高いものを、経験則を用いて検出します。 そのため、`encodings` の順番通りでない場合があります。

追加の情報なしに、 意図した文字エンコーディングを自動で検出する行為は、 全く役に立ちません。 これは、暗号化された文字列を鍵なしにデコードする行為に似ています。 "Content-Type" HTTP ヘッダのような、 データを転送された際に付いてくる情報や、 保存された文字エンコーディングに関する指示を指定することが常に望ましいです。

この関数は、全ての文字列が正しいバイト配列とは限らない マルチバイト文字列を指定するともっとも役に立ちます。 入力となる文字列に誤ったバイトが含まれていた場合、 そのエンコーディングは採用されません。

警告

# この関数の結果は正確ではありません

この関数の名前は誤解を招きやすいです。 この関数は 「検出」(detection) ではなく 「推測」"guessing" を行います。

この関数が行う「推測」は正確には程遠いので、 正しい文字エンコーディングを検出する用途に、この関数は使えません。

### パラメータ

`string`

  調べる対象の文字列。

`encodings`

  試す文字エンコーディングの一覧を指定します。 このリストは、文字列の配列または、 カンマ区切りのリストで指定できます。

  `encodings` が省略された場合、 または `null` の場合、 現在の detect_order ( mbstring.detect_order 設定オプション または mb_detect_order() で設定したもの) を使います。

`strict`

  `encodings` で指定された 文字エンコーディングのリストの全てに対して、 不正と判定された場合の振る舞いを指定します。 `strict` が `false` の場合、 もっとも近いと判定された文字エンコーディングが返されます。 `strict` を `true` にした場合、 `false` が返されます。

  `strict` のデフォルト値は mbstring.strict_detection 設定オプションで指定できます。

### 戻り値

検出した文字エンコーディングを返します。 指定したエンコーディングの全てに対して、不正と判定された場合は `false` を返します。

### 変更履歴

バージョン | 説明
--- | ---
8.2.0 | mb_detect_encoding() は、 以下のテキストでないエンコーディングを返さなくなりました: `"Base64"`, `"QPrint"`, `"UUencode"`, `"HTML entities"`, `"7 bit"`, `"8 bit"`

### 例

例1 mb_detect_encoding() の例

    <?php

    $str = "\x95\xB6\x8E\x9A\x83\x52\x81\x5B\x83\x68";

    // 現在のdetect_orderで文字エンコーディングを検出
    var_dump(mb_detect_encoding($str));

    // "auto" は mbstring.language の設定を使って展開されます
    var_dump(mb_detect_encoding($str, "auto"));

    // 文字エンコーディングをカンマ区切りのリストで指定することで、encodings 引数を指定
    var_dump(mb_detect_encoding($str, "JIS, eucjp-win, sjis-win"));

    // encodings 引数を配列で指定
    $encodings = [
      "ASCII",
      "JIS",
      "EUC-JP"
    ];
    var_dump(mb_detect_encoding($str, $encodings));
    ?>

上の例の出力は以下となります。

    string(5) "ASCII"
    string(5) "ASCII"
    string(8) "SJIS-win"
    string(5) "ASCII"

例2 `strict` パラメーターの効果

    <?php
    // 'áéóú' は ISO-8859-1 でエンコードされています
    $str = "\xE1\xE9\xF3\xFA";

    // この文字列は、ASCII または UTF-8 的には正しくありませんが、
    // UTF-8 がもっとも近いと判定されます
    var_dump(mb_detect_encoding($str, ['ASCII', 'UTF-8'], false));
    var_dump(mb_detect_encoding($str, ['ASCII', 'UTF-8'], true));

    // 正しいエンコーディングが見つかった場合、
    // strict パラメータを指定しても結果は変わりません
    var_dump(mb_detect_encoding($str, ['ASCII', 'UTF-8', 'ISO-8859-1'], false));
    var_dump(mb_detect_encoding($str, ['ASCII', 'UTF-8', 'ISO-8859-1'], true));
    ?>

上の例の出力は以下となります。

    string(5) "UTF-8"
    bool(false)
    string(10) "ISO-8859-1"
    string(10) "ISO-8859-1"

場合によっては、同じバイト配列が、 複数の文字エンコーディング的に正しいかもしれませんが、 どの解釈が意図されたものなのかを知ることは不可能です。 たとえば、 バイト配列 "\xC4\xA2" は、 以下のように解釈できます:

- "Ä¢" (U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS のあとに、U+00A2 CENT SIGN が続いたもの) これらは、ISO-8859-1, ISO-8859-15, Windows-1252 でエンコードされたものと解釈できます。
- "ФЂ" (U+0424 CYRILLIC CAPITAL LETTER EF のあとに、 U+0402 CYRILLIC CAPITAL LETTER DJE が続いたもの) これは、ISO-8859-5 でエンコードされたものと解釈できます。
- "Ģ" (U+0122 LATIN CAPITAL LETTER G WITH CEDILLA) これは、UTF-8 でエンコードされたものと解釈できます。

例3 複数のエンコーディングと一致した場合の効果

    <?php
    $str = "\xC4\xA2";

    // 3つ全てのエンコーディングに照らして正しい文字列ですが、
    // 最初のひとつが常に返されるとは限りません
    var_dump(mb_detect_encoding($str, ['UTF-8']));
    var_dump(mb_detect_encoding($str, ['UTF-8', 'ISO-8859-1', 'ISO-8859-5'])); // PHP 8.1 以降では、UTF-8 ではなく ISO-8859-1 が返されます
    var_dump(mb_detect_encoding($str, ['ISO-8859-1', 'ISO-8859-5', 'UTF-8']));
    var_dump(mb_detect_encoding($str, ['ISO-8859-5', 'UTF-8', 'ISO-8859-1']));
    ?>

上の例の出力は以下となります。

    string(5) "UTF-8"
    string(10) "ISO-8859-1"
    string(10) "ISO-8859-1"
    string(10) "ISO-8859-5"

### 参考

- mb_detect_order() - 文字エンコーディング検出順序を設定あるいは取得する

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open