PHPのマルチバイト関数で文字エンコーディング指定について

# 概要

PHPのマルチバイト関数の引数として文字エンコーディング名を指定する際は、実際の文字エンコーディング名以外も指定することができます。
その際の挙動や指定方法についてまとめようと思います。

> ※PHP8.2時点での仕様となります。

# 文字エンコーディング名の指定の種類

`mb_convert_encoding`のような文字エンコーディングを変換数関数ではfromとtoがあり、それぞれ指定できるものが異なります。

- fromとして指定できる文字エンコーディング名
  - サポートされる文字エンコーディング名
  - サポートされる文字エンコーディングのエイリアス名

> ※ 未指定は不可

- toとして指定できる文字エンコーディング名
  - サポートされる文字エンコーディング名
  - サポートされる文字エンコーディングのエイリアス名
  - 未指定（`null`も含む）
  - `auto`

> ※`auto`は複数エンコーディングを指定できる関数に限る
  

- その他
  - `pass`

## サポートされる文字エンコーディング名を指定

サポートされる文字エンコーディング／エイリアス名についての詳細は前日の記事を参照

https://qiita.com/bosshawk/items/3e292908fa0446becf01

## 未指定

未指定の場合の挙動は関数によって異なり、
- 設定(php.ini)のデフォルト値
- `mb_detect_order`のリスト
を利用するもの別れます。

### 設定のデフォルト値

 [mbstring.internal_encoding setting](https://www.php.net/manual/ja/mbstring.configuration.php#ini.mbstring.internal-encoding) が設定されていた場合、それを使います。
 設定されていない場合は、 [default_charset setting](https://www.php.net/manual/ja/ini.core.php#ini.default-charset) を使います。

[mb_convert_encoding](https://www.php.net/manual/ja/function.mb-convert-encoding.php) などの関数がこの挙動となります。

### `mb_detect_order`のリスト

[mb_detect_order](https://www.php.net/manual/ja/function.mb-detect-order.php) を実行した際と同じリストで動作するというものになります。
`mb_detect_order`の値は、php.iniで設定するか、関数を実行した際の引数で設定することができます。

[mb_detect_encoding](https://www.php.net/manual/ja/function.mb-detect-encoding.php) などの関数がこの挙動となります。

### 備考
 
`mb_convert_encoding`と同様の関数である[mb_convert_variables](https://www.php.net/manual/ja/function.mb-convert-variables.php)は、ドキュメント上は`mb_detect_order`が利用されますとなっていますが、現行の仕様上は未指定することができないと思われるため、ドキュメントのほうが間違っている(もしくは古い)のかもしれません。

> ソースコード上は、設定のデフォルト値を取得していましたが利用されないように見えたのでどっちなんだ...となりました。


## `auto`を指定

`auto`を指定した場合は、[mbstring.language](https://www.php.net/manual/ja/mbstring.configuration.php#ini.mbstring.language)で指定した言語によって対象となるリストが変わります。
設定が `Japanese` の場合は "ASCII,JIS,UTF-8,EUC-JP,SJIS" が対象のリストとなります。
また、`mbstring.language`が未設定の場合は、"ASCII,UTF-8"となります。


つまり、`mbstring.language`を設定しない場合は、`auto`を指定する意味はほぼないということにないります。


下記の関数などで`auto`を使用することができます。

- [mb_detect_encoding](https://www.php.net/manual/ja/function.mb-detect-encoding.php)
- [mb_convert_encoding](https://www.php.net/manual/ja/function.mb-convert-encoding.php)
- [mb_convert_variables](https://www.php.net/manual/ja/function.mb-convert-variables.php)

### 備考

文字エンコーディング検出順を設定するための関数である`mb_detect_order`の引数としても`auto`を指定することができます。
`mb_detect_order`の初期値は、[mbstring.detect-order](https://www.php.net/manual/ja/mbstring.configuration.php#ini.mbstring.detect-order) で設定できるので利用したい用途があるかはよくわからないです。

```php
ini_set("mbstring.language", "Japanese");

var_dump(mb_detect_order());    // "ASCII,UTF-8"

mb_detect_order("auto");
var_dump(mb_detect_order());   // "ASCII,JIS,UTF-8,EUC-JP,SJIS"
```
> https://3v4l.org/MQqm1

## `pass`を指定

`pass`が指定された場合は文字エンコーディングの変換は行われません。

下記の関数などで`pass`を使用することができます。
- [PHP: mb_http_output - Manual](https://www.php.net/manual/ja/function.mb-http-output.php)


# まとめ

文字エンコーディング名を指定方法と挙動についてまとめて思いましたが、やはりわかりづらい仕様となっていますね...。

`auto`を指定した場合や複数のエンコーディングをした場合は、文字エンコーディングの自動検出が実施され、完全な自動検出が不可能なことも相まって、PHPのバージョンにより挙動が異なることということが発生します。
基本的には、サポートされる文字エンコーディング名を明示的にしていするほうがよいと思われます。
(とはいえ現行で利用している場合はそうもいかないですよね...)


マルチバイト関数の引数で文字エンコーディング名以外を指定することがあれば、参考してもらえると幸いです。