4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ラクスAdvent Calendar 2023

Day 14

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

Posted at

概要

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

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

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

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

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

※ 未指定は不可

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

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

  • その他
    • pass

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

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

未指定

未指定の場合の挙動は関数によって異なり、

  • 設定(php.ini)のデフォルト値
  • mb_detect_orderのリスト
    を利用するもの別れます。

設定のデフォルト値

mbstring.internal_encoding setting が設定されていた場合、それを使います。
設定されていない場合は、 default_charset setting を使います。

mb_convert_encoding などの関数がこの挙動となります。

mb_detect_orderのリスト

mb_detect_order を実行した際と同じリストで動作するというものになります。
mb_detect_orderの値は、php.iniで設定するか、関数を実行した際の引数で設定することができます。

mb_detect_encoding などの関数がこの挙動となります。

備考

mb_convert_encodingと同様の関数であるmb_convert_variablesは、ドキュメント上はmb_detect_orderが利用されますとなっていますが、現行の仕様上は未指定することができないと思われるため、ドキュメントのほうが間違っている(もしくは古い)のかもしれません。

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

autoを指定

autoを指定した場合は、mbstring.languageで指定した言語によって対象となるリストが変わります。
設定が Japanese の場合は "ASCII,JIS,UTF-8,EUC-JP,SJIS" が対象のリストとなります。
また、mbstring.languageが未設定の場合は、"ASCII,UTF-8"となります。

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

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

備考

文字エンコーディング検出順を設定するための関数であるmb_detect_orderの引数としてもautoを指定することができます。
mb_detect_orderの初期値は、mbstring.detect-order で設定できるので利用したい用途があるかはよくわからないです。

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を使用することができます。

まとめ

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

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

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

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?