PHP mail()関数で日本語を文字化けさせずに送信する

PHPからメール送信することは可能です。
メールフォームなどに入力された内容をメールで送信することはよくあることです。

PHPには「mail関数」と呼ばれる、メールを送信する仕組みが標準で備わっています。
これを使えば割と簡単にメール送信できます。

ただ、よく文字化けします。
とくに日本語はよく化けます。

何とかならないものか四苦八苦しながらも対処いたしましたので、忘備録として記録いたします。

mail()関数とはこのような関数です

基礎情報として、mail()関数について記述します。
といっても以下のように記述するだけです。

mail( [送信先メールアドレス], [メールタイトル], [本文], [送信元メールアドレス]);

例えば、以下のように記述します。


mail(“sousin@office-obata.com”, “メールタイトル文”, ”本文 テキストテキスト・・・”, “moto@officeobata”);
※メールアドレスは実在しないものです。


なんだ簡単じゃないかと思い、さっそく実験してみました。

実験①:特に何も考えずmail送信してみました。

PHPでメール送信するだけならば、フォームを使わなくてもできます。
テスト用に以下のプログラムを作成しテストしてみました。

実際に受信してみた結果がこちらです。

OUTLOOKで受信したら特に問題はなかったのですが、Thunderbirdでメール受信してみたところ、「差出人」と「件名」が文字化けしました。

なんとなく理由は想像がつきます。

OUTLOOKは文字コードが「Shift-JIS」ベースですが、Thunderbirdは「UTF-8」

テスト用のPHPは日本語の文字コードを「Shift-JIS」で組んでおります。
Thunderbirdは日本語部分のデフォルトが「UTF-8」です。

なのでOUTLOOKでは文字化けせず、Thunderbirdは文字化けしたのだと思われます。

ちなみに、
メールの受信確認をする際は、OUTLOOKとThunderbirdの2つを使うと、問題点の検出がやりやすいです。
OUTLOOKだけでチェックすると、特定メーラー文字化けを見逃しがちです。

実験②:差出人、件名をUTF-8にしてみました

差出人、件名が文字化けしたので、ならばその2つを「UTF-8」に変換してみました。

その結果がこちらです。

なるほど。一方を直せば反対側がだめになるパターンです。
この場合、どうすればよいのでしょうか?

実験③:メールヘッダーを付け加えてみた。

そもそもベースの文字コードが違うメーラーの場合、Shift-JIS、UTF-8のどちらを使用しても、かならずどちらかのメーラーは文字化けします。

このような場合、どうすればよいのでしょうか?

ググって調べて見たところ、以下のような対策が必要だということがわかりました。

  • メールヘッダーに文字コードを記述するとメーラーは、メールヘッダーに記述された文字コードで表示される。

なるほど、表示する文字コードを事前に指定すれば良い。
ということがわかりました。

しかし、ここで疑問がわきました。
メールヘッダーってなに?PHPのmail関数でどうやって指定するの?

ちなみに、以前こんな記事も書いていました。

そういえば、PHPから送信するときにメールヘッダーを指定していないと思いました。
しかし、どうやって指定すればよいかわからなかったため、ググってさらに調べました。

その結果対応してみたものが、以下のコードになります。

急に複雑になりました。
要は、いままで「送信元情報」を設定していた部分にメールヘッダー情報を記述します。
メールヘッダーはむつかしくてよくわからないので、固定記述でコピペです。

その結果がこちらです。

さらにひどくなりました・・・・。
今度は本文も文字化けしました。

ただ、件名はどちらも正しく表示されています。
ひどいなりにも、一歩前進です。

まずは本文の文字化けを何とかします。

実験④:本文の文字化けを直す

メールヘッダーを記述したらなぜ本文が文字化けしたのか?
ちょっと焦る感じの現象ですが、冷静になって考えたら理由がわかります。

  • メールヘッダーには記載文字コードはUTF-8と記述した
  • 本文はもともと文字化けしていなかったのでShift-JISのまま

なんか理由が見えてきました。
これは本文を「UTF-8」に変換してやればよさそうです。

それがこちらです。

実験③との違いは、本文をUTF-8に変換を追加したのみです。

結果はこちら。

本文の文字化けが直りました。
文字コード変換は当たりでした。

残るは、差出人部分を何とかすればOKです。
しかしメールヘッダーをつけているのに、差出人だけなぜ文字化けするのでしょうか?
そして化けているのはOUTLOOKだけです。

考えてもよくわからなかったので、さらにググって調べました。
そしたら、次のようなことがわかりました。

  • 差出人はメールヘッダー内に記述されるため、MIME変換しなければならない。

なるほど、差出人名はメールヘッダー内だから、文字コード指定していても文字化けしていたようです。
でも疑問がわきました。
MIME変換って何?

実験⑤:差出人名をMIME変換をしてみる(注:失敗例)

PHPでMIME変換をググってみたら、あっさり疑問は解決しました。
mb_encode_mimeheader()というMIME変換してくれる関数がPHPにはありました。

差出人をこの関数を通せばMIME変換してくれます。
早速差出人をMIME変換する記述に書き換えてみました。

差出人部分のUTF-8変換をやめ、MIME変換してみました。
その結果がこちらです。

Thunderbird側は問題ありませんでしたが、OUTLOOK側が変な文字列になりました。
何がいけないのでしょうか?

PHPの記述を見直していたら、気づきました。
送信元メールアドレスごとMIME変換していました。

送信元情報は、

というように、日本語名とメールアドレスをまとめて気記述していました。
でもMIME変換は日本語部分だけでよいのではないかと思いました。

そこで送信元名と送信元メールアドレスを分離して記述することにしました。

実験⑥:差出人名をMIME変換をしてみる(成功例)

送信元情報を分割し、日本語名だけをMIME変換するように直しました。
それがこちらです。

日本語部分だけをMIME変換し後から結合します。

その結果がこちらです。

OUTLOOKもThunderbirdも文字化けしなくなりました。
かなりしんどかったですが、無事解決することができました。

メールを文字化けさせないポイント

  • メールヘッダーを正しく記述すること。
  • そして日本語部分を正しい文字コードに変換すること。
  • 差出人日本語名はMIME変換すること。

この3つが大事であることをよくよく学びました。

mail送信関数にはmb_send_mail()というものもあります。
ただ、うまく送信できない。文字コード変換がかえって大変などの理由からmail関数のみでやってみました。

これでmail関数だけでそれなりにメール送信ができることがわかりました。
また一つ良い経験をいたしました。

今回のレポートは以上です。
読んでいただいてありがとうございました。


ホームページに関するお悩み事やご相談事がございましたら私どもまでご連絡ください。 鋭意ご対応申し上げます。
ホームページのご提案もさせていただいております