Help us understand the problem. What is going on with this article?

EUC-JP環境でphpのstr_replaceを使い全角スペースの置換でバグが発生する件

はじめに

表題の通り、本記事は以下の状況にて発生する現象の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

誤った説明の箇所があれば、コメントいただけると嬉しいです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした