🦝
【php】HTML-ENTITIESの文字化けが気になる
【旧】mb_encode_numericentity
今までmb_convert_encoding
を使っていたんだけど、ソースコードの文字が記号になってしまうのが少し気になっていた。
$dom = new DOMDocument('1.0','UTF-8');
$dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'));
どうやらHTML-ENTITIES
に変換してしまうと文字列は数値文字参照(エンティティ化)されてしまうらしい。
【新】mb_encode_numericentity
ブラウザでの表示上は普通だけど気になる……ので、別の関数を使ってみた。
$dom = new DOMDocument('1.0','UTF-8');
$dom->loadHTML(mb_encode_numericentity($content,[0x80, 0x10ffff, 0, 0x1fffff]));
正直よくわからないのでこの記事からコピペしてきた。
コード領域の解読
コピペエンジニアの称号は不名誉であり、正しく設定できているか不安もあったから調べてみた。
変換マップの構造
Copilotによると、第二引数の変換マップの構造は以下のとおり。
- 範囲の開始(コードポイント):
変換対象となる文字コードの開始値です。この値は16進数で指定されます。 - 範囲の終了(コードポイント):
変換対象となる文字コードの終了値です。この値も16進数で指定されます。 - 基数オフセット:
数値エンティティを生成する際の基数オフセットです。この値は変換時に使用する追加の基数を指定します。例えば、オフセットが0の場合、単純にそのままの数値エンティティが生成されます。 - エンコード方式:
数値エンティティのエンコード方法に関する追加情報を指定します。通常はそのままの形式を保持するため、0x1fffffが使用されますが、必要に応じて変更することができます。
というわけで、それぞれの数値の根拠を探しに行く。
範囲の開始(0x80)
0x80
は10進数で128
に相当する。
(0x
は16進数であることを表し、80
は16*8+16*0
で128)
0~127に該当する文字は互換性があり、エンコード無しでも問題なく表示できる……らしい。
この部分はASCIIコード(7bit)に該当していて、アルファベット・数字・記号が表現されている。
これってキーボードの割り当てにも使用されてるのかな。
範囲の終了(0x10ffff)
0x10ffff
はUnicodeのコードポイントの最大値で、文字はここまでということになっている。
基数オフセット(0)
文字通りオフセットなので、0以外だと対応文字がズレていくんじゃないかな。
エンコード方式(0x1fffff)
Unicodeは21ビットまで表現できることになっていて、エンコード方式に0x1fffff
を設定すると概ねすべての文字を解釈できることになる……らしい(?)。
(0x
は16進数を表し、1fffff
は1 1111 1111 1111 1111 1111
となり21ビットを表す)
調べた感じコード領域の設定はこれで問題なさそうだけど、文字コードって難しいね。
Discussion