✒️

PHPでmb_convert_encodingを使って `㈱` をSJISに変換したら?になったのなんで?

2021/08/17に公開

はじめに

PHPでmb_convert_encodingを使って (かっこ株)をSJISに変換したら ? になってしまいました。
原因は適切な文字エンコーディングが設定されなかったためです。
今回でいうと (かっこ株)を使うのに SJIS 設定しちゃダメでした。

何でダメか、っていうかSJISって何?とかを整理することにしました。

結論

  • mb_convert_encodingで、不適切なエンコーディングを指定すると ? に変換される場合がある
  • SJISはShift_JIS系の中の一つを指定するエイリアス
    • Shift_JISを指定するエイリアス
  • (かっこ株)などのNEC特殊文字等はWindows-31J(エイリアス:SJIS-WIN)で対応している場合がある

前提

  • CotEditorを使いました
    • Shift_JIS系に対応したエディタがあれば代用可能です。「やってみた」で書いたコードの動作確認に使っただけです

整理してみた

mb_convert_encodingとは

文字エンコーディングを変換するメソッドです。
stringに指定したstring( or array)を、from_encodingに指定したエンコーディングからto_encodingに指定した エンコーディング に変換します。

https://www.php.net/manual/ja/function.mb-convert-encoding.php

SJISとは

mb_convert_encodingで指定できるエンコーディングの一つです。

https://www.php.net/manual/ja/mbstring.supported-encodings.php

IANA文字セットの登録名でいうと Shift_JIS です。JIS X0201:1997 / JIS X0208:1997 を合成したものです。
さらに言うと、これはCP932のコードセットには非対応です。
「Shift_JIS系」のエンコーディング の一つです。

https://www.php.net/manual/ja/mbstring.encodings.php

「Shift_JIS系」のエンコーディング

mb_convert_encodingで指定できるエンコーディングの中で、「Shift_JIS系」のエンコーディングは以下です、

  • SJIS
  • SJIS-win
  • SJIS-mac
  • SJIS-Mobile#DOCOMO
  • SJIS-Mobile#KDDI
  • SJIS-Mobile#SOFTBANK

Windows-31Jについて

Windows-31J(MS932)はShift_JISと同じエンコーディング方式使用しますが、文字集合が違います。

https://www.php.net/manual/ja/mbstring.encodings.php

端的に言うと、こちらは (かっこ株)を始めとしたNEC特殊文字にも対応しています(その他にも色々ありますが、割愛します)

Shift_JISとWindows-31Jの指定方法

  • Shift_JISの指定方法: SJIS を指定する
  • Windows-31Jの指定方法: SJIS-WIN を指定する

https://www.php.net/manual/ja/mbstring.encodings.php

やってみた

  • Shift_JISとWindows-31Jへ変換するコードを書く
test_sjis.php
<?php
    $char = '㈱ほげhoge';
    echo mb_convert_encoding($char, 'SJIS', 'UTF-8').PHP_EOL;
?>
test_sjiswin.php
<?php
    $char = '㈱ほげhoge';
    echo mb_convert_encoding($char, 'SJIS-WIN', 'UTF-8').PHP_EOL;
?>
  • 書いたコードを実行してみる
php test_sjis.php > result_sjis.txt
php test_sjiswin.php > result_sjiswin.txt
  • エディタで開いてみる

おわりに

「Shift_JIS」でお願いします。って言われたら、対エンジニアなら「どのエンコーディング方式ですか?」と確認しましょう。
非エンジニアなら (かっこ株)とか入るのか確認しましょう。

もっというと、Shift_JISを使わない方法を一緒に考えたいですね、正直w

参考

Discussion