phpのmb_send_mailの文字化けについて考える

小川です。

phpでメールを送る部分を以前書いたコードからコピって使用しようとしたら気になった。
mb_language()mb_internal_encoding()
この2つはなんなんだ。。。

調べるとmb_language()の設定はmb_send_mailのエンコーディングに使用しているようです。
mb_language()はmb_send_mailを使用するときに必ず書く必要はなく、書かない場合は
apacheで読み込んでいるphp.iniのmbstring.languageの設定を使うようです。

mb_internal_encoding()は内部文字エンコーディングの設定と取得ができます。
割とこいつが重要でHTTPの入出力等での文字化けにかかわってきます。

この設定とスクリプトを書いている文字コードが合わないで文字化けするのが大半な気がします。
mb_internal_encoding()のデフォルト設定はapacheで読み込んでいるphp.iniのmbstring.internal_encodingになります。

php.iniのmbstring.internal_encodingをコメントアウトしているとISO8859-1になりました。
下記のサンプルはスクリプト書いた文字コードがUTF-8でmbstring.internal_encodingがUTF-8以外の場合です。

mbstring.internal_encodingがUTF-8であればmb_internal_encoding()の記述は必要ありません。
スクリプト書いた文字コードがEUC-JPでmbstring.internal_encodingがUTF-8の場合等に
mb_internal_encoding('EUC-jP')を設定しましょう。

文字化けを回避したメールを送るコードのサンプルは下記になります。

function sendMail($data) {
  mb_language("ja") ;
  mb_internal_encoding("UTF-8") ;
  $mailto="hoge@hoge.com";
  $subject= "お問い合わせ";
  $content="法人名:" . $data['company_name'] . "\n".
  "法人名(ふりがな):" . $data['company_name_kana'] . "\n" .
  "ご担当者名:" . $data['name'] ."\n".
  "ご担当者名(ふりがな):" . $data['name_kana'] . "\n" .
  "Email:" . $data['mail'] . "\n\n".
  "お問い合わせ内容:" . $data['body']."\n";

  $header ="From:" . mb_encode_mimeheader($data['name']) . "<".$data['mail'].">";
  return mb_send_mail($mailto, $subject, $content, $header);
}

スクリプト書いてる文字コードとmbstring.internal_encodingの文字コードが違う場合、
上記以外にもmb_send_mailに値を渡す前に値をmbstring.internal_encodingで設定した文字コードに変換するというやり方もあります。

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

夏のTechRachoフェア2019

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ