#はじめに
表題の通り、本記事は以下の状況にて発生する現象のTipsとなります。
- 文字コードがEUC-JPである環境で
- phpのstr_replace関数を使用し
- 全角スペースを置換した場合
- 想定していない単語まで置き換わってしまう
#発生した現象
DBに入っている値がなんだかおかしい、というところからスタートした。
「ァー」が「ゼ」に代わって保存されているらしい。
クリストファーがクリストフゼといった具合。
プログラムを追っていくと、どうやらDBに値を投入する前の処理がおかしくなっている模様。
$trimmed_str = str_replace(" ", "", $str);
結論として、「全角スペースを置換すると'ァー'という文字列が影響を受ける」という現象だった。
#原因
環境の文字コードがEUC-JPであることが原因だった。
EUC-JPはマルチバイト文字であり、全角文字は複数の16進数の組み合わせによって表現される。
参考: https://qiita.com/mpyw/items/a8dba1b80fe68523b8eb
下記のURL先の表のようなマッピングがされている。
http://charset.7jp.net/euc.html
表に当てはめると、「ァ」は'0501'、「ー」は'01bc'となる。
そして全角スペースは'0101'...
要するに、'050101bc'から'0101'を除外していしまい、'05bc'、つまり「ぜ」に変換されてしまったのだ。
#対策
この状況を脱却するために、以下の対処をすることで解決できる。
##EUC-JPを脱却する
環境の文字コードをEUC-JPからUTF-8に変更することで解決できる。
UTF-8では先頭バイトと後続するバイトで領域が分かれているため、今回の現象のようにほかの文字の組み合わせと混同することがない。
原因の箇所で紹介させていただいた記事に詳細が書かれているので、詳しくはそちらを参照してほしい。
##マルチバイト文字対応の関数へ修正する
とはいえ、軽々に文字コードを修正できないケースもある。
(古の環境を修正せざるを得ないつらい状態の方もいるだろう)
この場合、マルチバイト対応の関数へ移行することで解決する。
$trimmed_str = mb_ereg_replace(" ", "", $str);
mb_ereg_replaceはマルチバイト対応なので、文字の組み合わせをその文字と混同しない。
https://www.php.net/manual/ja/function.mb-ereg-replace.php
誤った説明の箇所があれば、コメントいただけると嬉しいです。