PHPでmb_send_mailしたら半角スペースが「?」になってしまう問題の解決法

php・MySQL・Web開発

PHPで、

・フォームから投稿されたデータをDBに保存&メールで送信

という自作スクリプトがあります。

ここで、普通にフォームに文字を入力してPOSTした場合は何も問題なく想定どおりに動作します。

しかし、いったん投稿データをDB(MySQL)に格納し、それを取り出してフォームに表示(inputタグのvalueにhtmlspecialchars関数をかませて表示)してPOSTした場合、なぜか送信したメールに含まれる投稿データ中の「半角スペース」が「?」になってしまう問題が発生しました。ブラウザに表示されるフォームのinput枠や、HTMLソースで見ても、「?」にはなっていません。あくまでもメール送信したときだけ半角スペースが「?」になります。

各種文字コード設定なども全て適切にやっているし、何が原因なのかサッパリわからない・・・と何日も悩みました。が、ググってみたらドンピシャのページを発見。

【参考】UTF-8の半角スペースについて – とりあえず落ち着け

結論から書くと、このページで紹介されている通りに

一度変換してみて?が混入してたらこのコードを足してみよう。(PHP専用)

$content = str_replace( “\xc2\xa0″, ” “, $content );

書いてある通り「C2A0」を削除するコード。これで?は出なくなりました。

・・・というコードによって問題が解決しました!

このページによると、

UTF-8で書かれたモノをShift-JISやEUCに変換した際に不可解な”?”が入っていたら「C2A0」が入ってる恐れがある。

とのことですが、私はPHPもMySQLもUTF-8に統一しており、Shift-JISやEUCには変換しておりません。

mb_send_mailがISO-2022に変換するので、そこが問題なのかとも思いました。しかし、前述したように、普通にフォームに(キーボードから手動で)データを入力した場合はメール送信しても文字化けせず、いったんMySQLに格納したデータの場合のみ、メール送信したときに半角スペースが「?」となってしまう問題が発生している。つまり、mb_send_mailがISO-2022に変換する件は今回の問題とは無関係ということが分かります。

ということは、やはりMySQLに絡むどこかに問題があるということになりそうです。

怪しいなと思っている点は、

  1. PDOでの接続時に「SET NAMES utf8」している
  2. MySQL の接続照合順序が「utf8_unicode_ci 」になっている

1については、なんか「SET NAMES utf8」はダメで、PDOのインスタンス生成時に文字コードを含めろとかなんとかいう記述をどこかで見たような記憶があるので。

2については、一口にUTF-8と言ってもいくつか種類?があって、その辺の絡みなのかな?と。詳しくは↓

【参考】utf8_unicode_ci に対する日本の開発者の見解 – かみぽわーる

【参考】utf8_general_ciとutf8_unicode_ci – 技術メモ帳

【参考】MySQLの照合順序 – Qiita

まあなんだか難しすぎて私にはよく分からないのですが、「とりあえず落ち着け」様のおかげで目の前の問題が解決したので、とりあえず落ち着きました。

日本語はいつも文字コードとの戦いで、つくづくコンピュータと相性が悪い言語ですね・・・。まあ日本語に限らずマルチバイト文字は全て同じ問題を抱えているとは思いますが。

コメント

タイトルとURLをコピーしました