![eyecatch php](https://nodoame.net/wp-content/uploads/eyecatch_php_20171221.jpg)
【PHP】PHPで機種依存文字を変換する場合は文字コードをSJIS-winにしてから!
2019/05/11
PHPでCSVファイル取込機能を作成中、機種依存文字である「㈱」を「(株)」(半角カッコ・株・半角カッコ)に変換しようとした時にはまってしまったので、その対策方法を忘備録としてポストします。
機種依存文字を変換する際の文字コードは「SJIS-win」と指定する
上手くいかないこと
作成しているシステムでCSVフォーマット(文字コードはSJIS)のファイルからインポートする機能をつけました。
その時にありがちですが、社名や備考などに含まれている機種依存文字の「㈱」を「(株)」に変換しようとしたら、全然うまく行かない。
シンプルに str_replace() で当てても変換されない始末。
CSVファイル取込・変換の基本的な流れは以下の感じ。
- CSVファイルをオープン
- 全体の文字コードを SJIS から UTF-8 に変換
- 機種依存文字を変換
かなり単純に書きましたが、特に変なことはしていないと思います。
悶々と作業していたのですが、急に思い出したことがありました。
そうなんです、やつらの文字コードは単純な SJIS ではなく「SJIS-win」という文字コードなんですね。
SJIS-winとは
SJIS-winとはなんぞやというのは、以下のサイト様で分かりやすく書いてくれています。
http://fdays.blogspot.jp/2011/03/php-sjis-sjis-win.html
重要なのはこの辺り。
SJISとSJIS-WINで何が違うの?
SJIS-WINの方が文字が多い。
よく使うところでは、下記のような文字はSJISーWINにはあるがSJISにはない。
- 丸数字 (①②③...⑳)
- ローマ数字 (ⅠⅡⅢ...Ⅹ、ⅰⅱⅲ...ⅹ)
- カッコ付きの株 (㈱)
- はしご高[はしごたか] (髙)
- たつ崎[たつさき、たちさき] (﨑)
単純な SJIS には含んでいないってことなんですね。
解決方法
じゃあどうすりゃいいんだ、って事で、良いのか悪いのは分かりませんが、以下の様な関数を作ってみました。
replaceStrKishuizon()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
function replaceStrKishuizon($subject) { // 現在の文字コードを取得 $_encode = mb_detect_encoding($subject, "UTF-8,SJIS-WIN,SJIS,EUC"); // SJIS-winに変換 if ($_encode != "SJIS-win") { mb_convert_encoding($subject, "SJIS-win", $_encode); } $search = array('Ⅰ','Ⅱ','Ⅲ','Ⅳ','Ⅴ','Ⅵ','Ⅶ','Ⅷ','Ⅸ','Ⅹ','①','②','③','④','⑤','⑥','⑦','⑧','⑨','⑩','№','㈲','㈱'); $replace = array('I','II','III','IV','V','VI','VII','VIII','IX','X','(1)','(2)','(3)','(4)','(5)','(6)','(7)','(8)','(9)','(10)','No.','(有)','(株)'); $ret = str_replace($search, $replace, $subject); // UTF-8に変換 $result = mb_convert_encoding($ret, 'UTF-8', "SJIS-win"); return $result; } |
変換する文字種にはもっと色々と入れるべきなんだと思いますが、今回は(サンプルってことで)とりあえず23種類。
使い方
1 |
$company = replaceStrKishuizon($company); |
CSVをオープンしてUTF-8に変換後、氏名やら住所やら、を登録用配列に入れる際に、会社名($companyとします)に対して先ほどの関数を施します。
やってることは、UTF-8に変換されている $company を SJIS-win にコンバート。
コンバート後の $company に含まれる「㈱」を「(株)」に変換し、再度 UTF-8 に変換してリターン。
かなり泥臭いですが、なんとか無事に変換はできました。
もっとスマートな方法はいくらでもあると思うのですが、とりあえず思いついたのがこの方法なので、何かの際には試してみてやってください。