はじめに
これはPHP8.1を利用していて遭遇したmb_detect_encoding
とmb_convert_encoding
に関する不思議なお話です。
それでは行ってみましょう。
用意するプログラム
test.php
<?php
echo 'ステップ1:文字列をそのままmb_detect_encodingしてみる' . PHP_EOL;
$str = 'テスト';
echo $str . PHP_EOL;
echo '文字コード:' . mb_detect_encoding($str) . PHP_EOL;
echo '' . PHP_EOL;
echo 'ステップ2:文字列をUTF-8からSJISに変換してみる' . PHP_EOL;
$str2 = mb_convert_encoding($str, "SJIS", "UTF-8");
echo $str2 . PHP_EOL;
echo '文字コード:' . mb_detect_encoding($str2) . PHP_EOL;
echo '' . PHP_EOL;
echo 'ステップ3:文字列をSJISからUTF-8に再度変換してみる' . PHP_EOL;
$str3 = mb_convert_encoding($str2, "UTF-8", "SJIS");
echo $str3 . PHP_EOL;
echo '文字コード:' . mb_detect_encoding($str3) . PHP_EOL;
echo '' . PHP_EOL;
実行結果
ステップ1:文字列をそのままmb_detect_encodingしてみる
テスト
文字コード:UTF-8
ステップ2:文字列をUTF-8からSJISに変換してみる
�e�X�g
文字コード:
ステップ3:文字列をSJISからUTF-8に再度変換してみる
テスト
文字コード:UTF-8
考察
ステップ1とステップ3は想定通りの結果ですが、ステップ2だけ文字コードの識別がおかしいですね。
下記の記事にも記載があるのですが、どうやらPHP8.0系からPHP8.1系になったタイミングで内部の仕組みが変わったことに起因しているっぽい感じがしますよね。
ステップ2で明示的に
echo '文字コード:' . mb_detect_encoding($str2, 'SJIS') . PHP_EOL;
と記載した場合はちゃんと文字コードがSJISであると認識してくれるので、間違ってはいなさそうではあります。
他の文字コードを指定した場合、文字コードが空欄となりましたので、やはりそうなのでしょう。
皆さんの記事でも紹介されている通り、こういった変更がシステムに影響を及ぼすこともあるので、気をつけましょう。
mb_convert_encoding
こちらも内部ではmb_detect_encoding
を使用しているので、やはり影響があります。
fromにauto
を設定しても、おかしくなります。