10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

これはPHP8.1を利用していて遭遇したmb_detect_encodingmb_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を設定しても、おかしくなります。

10
2
2

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
10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?