PHPで日本語メールを送る - 基本編に引き続き、
今回は応用編をお送りします。
基本編で解説したmb_send_mailを使えば
シンプルなメールを送るには十分な機能がありますが、
それ以上に複雑なこと、例えばHTMLメールや添付ファイルを
使ったメールにはmb_send_mailは使えません。
mail関数を使ってヘッダにガリガリとメールの仕様に
そって書けば送れるのですが、それではあまりに
大変なので、ライブラリを使います。
ライブラリを使った日本語メール送信
PHPで複雑なメールを送るのに使えるスタンダードな
ライブラリとしては、PEAR::MailとPHPMailerが有名です。
(ただし、両ライブラリとも日本語メールには対応していないので、
そのままでは文字化けしてしまいます)
PEAR::MailはPHPの公式ライブラリのPEARで採用されていますし、
PHPMailerもXOOPSやSymfonyなど有名なオープンソースの
プロジェクトで採用されるなど、どちらも十分な実績がある
メールライブラリです。
PEAR::Mailの方がPEARに採用されているだけあって
良く取り上げられることが多く、また日本語での
紹介記事も多いのですが、私個人としては
PHPMailerの方をオススメします。
理由としては、PHPMailerの方が圧倒的にカンタンで
使いやすいからです。
例えば、添付メールを送るコードを見比べてみると、
PEAR::Mailでは
-
//ライブラリ読み込み
-
require_once("Mail.php");
-
require_once("Mail/mime.php");
-
-
//言語設定、内部エンコーディングを指定する
-
-
//日本語添付メールを送る
-
$to = "kawamura@example.com"; //宛先
-
$subject = "例の件について"; //題名
-
$body = "資料を送ります"; //本文
-
$from = "masaki@example.com"; //差出人
-
$fromname = "山本 正喜"; //差し出し人名
-
$attachfile = "./file.zip"; //添付ファイルパス
-
-
-
-
$mime = new Mail_Mime("\n");
-
$mime->setTxtBody($body);
-
-
//添付ファイル追加
-
$mime->addAttachment($attachfile,"application/octet-stream");
-
-
$body_encode = array(
-
"head_charset" => "ISO-2022-JP",
-
"text_charset" => "ISO-2022-JP"
-
);
-
-
$body = $mime->get($body_encode);
-
-
$headers = array(
-
"To" => $to,
-
);
-
-
$header = $mime->headers($headers);
-
-
$return = $mail->send($to,$header,$body);
-
if (PEAR::isError($return)){
-
echo("メールが送信できませんでした エラー:".$return->getMessage());
-
}
こう書きます。
。。。。。
もう、何ですかこれは? という感じですね。
いえ、メールの仕様に沿ってしっかりとクラス化
されているので、確かにメールの仕様を理解してる人には
わかりやすいと思いますが・・・。
このライブラリを使うには、メールのヘッダ構造や
MIMEのルールなどを知る必要があり、ただ添付メールを
送りたいというだけの開発者にはまわりくどすぎます。
(引数の渡し方もいちいち複雑!)
一方、PHPMailerでは
-
//ライブラリ読み込み
-
require("./phpmailer/class.phpmailer.php");
-
-
//言語設定、内部エンコーディングを指定する
-
-
//日本語添付メールを送る
-
$to = "kawamura@example.com"; //宛先
-
$subject = "例の件について"; //題名
-
$body = "資料を送ります"; //本文
-
$from = "masaki@example.com"; //差出人
-
$fromname = "山本 正喜"; //差し出し人名
-
$attachfile = "./file.zip"; //添付ファイルパス
-
-
-
$mail = new PHPMailer();
-
$mail->CharSet = "iso-2022-jp";
-
$mail->Encoding = "7bit";
-
-
$mail->AddAddress($to);
-
$mail->From = $from;
-
-
//添付ファイル追加
-
$mail->AddAttachment($attachfile);
-
-
if (!$mail->Send()){
-
echo("メールが送信できませんでした。エラー:".$mail->ErrorInfo);
-
}
こう書けます!
いいですねー。シンプルです。
送りたいメールのパラメータ一つ一つに、
クラスのメソッドやプロパティが対応しており、
とても直感的でわかりやすいです。
※補足
Bodyだけmb_encode_mimeheaderがないのは、
本文はヘッダではないからです。
ただ、以下の点をなんとかしたいところです。
・日本語を使う場合CharSetやEncodingを指定する必要あり
・$mail->From = $from など、プロパティに値を
直接入れたくない (しかも一文字目が大文字)
・毎回mb_encode_mimeheaderやmb_convert_encodingが面倒
・addCcやaddBccはあるのに、宛先はaddToではない。(addAddress)
・とても長い題名のメールが文字化けする
というわけで、気に入らないならラッパークラスを作りましょう。
PHPMailerの日本語ラッパークラス JPHPMailer
JPHPMailer - ここからダウンロード (PHP4/PHP5 両対応)
※PHPMailer本体が別途必要です。
JPHPMailerでPHPMailerを改良したのは次の点です。
・CharSetやEncodingの設定を不要に
・addAddress()をaddTo()へ (addAddressも使えます)
・From,Subject,Bodyなど、プロパティを直接扱うものを
メソッドを通して設定するように
・エラーメッセージの取得をgetErrorMessage()メソッドで。
・mb_*関連の変換が不要に。(引数でそのまま渡すだけ)
・題名が長いメールでも文字化けが起きないように。
このラッパークラスを使うと、先ほどの添付メールの例では
-
//ライブラリ読み込み
-
require("./jphpmailer.php");
-
-
//言語設定、内部エンコーディングを指定する
-
-
//日本語添付メールを送る
-
$to = "kawamura@example.com"; //宛先
-
$subject = "例の件について"; //題名
-
$body = "資料を送ります"; //本文
-
$from = "masaki@example.com"; //差出人
-
$fromname = "山本 正喜"; //差し出し人名
-
$attachfile = "./file.zip"; //添付ファイルパス
-
-
-
$mail = new JPHPMailer();
-
-
$mail->addTo($to);
-
$mail->setFrom($from,$fromname);
-
$mail->setSubject($subject);
-
$mail->setBody($body);
-
-
//添付ファイル追加
-
$mail->addAttachment($attachfile);
-
-
if (!$mail->send()){
-
echo("メールが送信できませんでした。エラー:".$mail->getErrorMessage());
-
}
こう書けます。
ずっと自然になりました。
何よりmb_*がきっちり隠蔽されてるところがポイントです。
HTMLメールを送る場合は、
-
//ライブラリ読み込み
-
require("./jphpmailer.php");
-
-
//言語設定、内部エンコーディングを指定する
-
-
//日本語HTMLメールを送る
-
$to = "kawamura@example.com"; //宛先
-
$subject = "例の件について"; //題名
-
$htmlbody = "<b>資料</b>を送ります"; //HTML本文
-
$altbody = "資料を送ります"; //代替テキスト本文
-
$from = "masaki@example.com"; //差出人
-
$fromname = "山本 正喜"; //差し出し人名
-
-
-
$mail = new JPHPMailer();
-
-
$mail->addTo($to);
-
$mail->setFrom($from,$fromname);
-
$mail->setSubject($subject);
-
$mail->setHtmlBody($htmlbody);
-
$mail->setAltBody($altbody);
-
-
if (!$mail->send()){
-
echo("メールが送信できませんでした。エラー:".$mail->getErrorMessage());
-
}
こうなります。
代替テキスト付きHTMLメールもカンタンに送ることができます。
※代替テキストは、メールソフトがHTML表示に
対応していない場合に代わりに表示されるテキストです。
-----------------------------------------------
長くなってしまいました。
JPHPMailerは今回の為に簡単に作ったものなので、
必要な機能があれば自由にカスタマイズしてください。
(ライセンスはLGPLです)
PEAR::MailやPHPMailerなど、PHPには優れたライブラリが
多数あるのですが、今回の様に日本語が使えなかったり、
それぞれのクラスで設計思想が違うのでメソッド名や
引数の渡し方などが気に入らなかったりするものです。
そういう時は、自分好みにクラスを継承したラッパーを
作ってあげるとぐっと使い勝手が良くなります。
こういうちょっとしたカスタマイズを覚えると、
様々なライブラリを自由に取り入れる事が
できるようになるので、是非挑戦してみてください!
関連した記事:
■ IT経営実践会
EC studio が長年培ってきた全てのIT活用ノウハウをマニュアルで提供!
国内初のGoogle Appsを利用した会員サービスです。
会員専用の掲示板による交流や
定期的に勉強会も実施しています。
中小企業の利益を増やす、IT経営実践会


この記事にTwitterでコメント



































ページの先頭に戻る
はじめまして。個人でPHPの勉強をしています。
JPHPMailerありがたく使わせて頂きます!
ひとつわからなかったことがあるのですが、
どうして題名と差出人名だけ、
mb_convert_encodingの第三引数が他と違う指定になっているのでしょうか?
UTF-8環境で動かそうと思ったので、
$in_enc=”UTF-8″としたら動くかなと思ったんですが、
そのときにこの2つの項目で引っかかってしまったので、
ちょっと気になりました。
特別な意味があるのかなぁと思ったので、
もしよろしければ教えてください!
コメントありがとうございます。
ご指摘していただいた箇所ですが、特に意味はなく修正し忘れていました箇所でした、、。
JPHPMailerを作った時に、内部エンコーディングを変更しやすいようにしようと後でin_encを足したのですが、全てのメソッドに反映されていなかった様です。
修正してアップしました。
JPHPMailerは思ったよりも大きな反響をいただけたので、バージョンアップ版を作成しようと思っていますのでご期待ください!
参考にさせてもらっています。
クラスに関して長いことさぼっていて、今日はじめてまともに勉強したので、とんちんかんな事を書いているかも知れませんが質問します。
外部メールサーバーをSMTP認証で使用しているのですが、PHPMailerを利用したときは、送れるのですが、JPHPMailerを利用したときはエラーになります。
親クラスのメンバ変数は子クラスでは特に宣言しなくても使えると理解しているのですが、何か間違っているのでしょうか?
もしよかったら、ご教示ください。
とても助かりました
phpでのメール送信はやっていましたが、このページのおかげでやりたいことを5分程度ですぐにできました。
大変有益な情報をありがとうございます。
こちらのJPHPMailerをちょこっとだけカスタマイズして、CakePHPで使えるようにしてみました。ありがとうございます。
一応LGPLとして配布していますが、なにか問題等ありましたらご連絡ください。
http://blog.tofu-kun.org/080528155319.php
>zaruさん
おお~、ありがとうございます。
全然問題ありません!
貴重なClassご提供ありがとうございます。
またご丁寧な解説非常に助かります。
質問させていただきたいのですが、
BCCを数多く指定したいときや添付を複数つけるとき
はどのような方法があるのでしょうか。
ご回答頂ければ幸いです。
よろしくお願いいたします。
とても参考になりました。
ところで、添付ファイル名ですが、これを日本語に変換して添付するなんてできないでしょうか?
Perlの時の自作のスクリプトではできていたので、ヘッダー的にはできるのですが、PHPMailerにはそのような関数が追加されてないかな?と、思ったもので。。。
>Pavoさん
addBccなどを複数回呼び出せばokです。
addXXXというメソッドは、どんどん追加されていきます。
添付ファイルもできると思います
>ともあきさん
おそらく、addAttachmentをオーバーライドすればできそうですね。
addAddressなどと同様に内部でencodeMimeheaderをたたけばできるのではないかと思います。
PHPMailerもバージョンアップしているようで、JPHPMailerの次期バージョンを作ろうかと思ってますので、その時に機能追加してみます!
http://q.hatena.ne.jp/1202147708
のような現象に私もなっていますが、
何か解決方法ってありますか?
特定の環境だと件名の途中で改行が入っているのか、
20文字のマルチバイト文字くらいの件名で全然長くないのに、
件名が途中で途切れてしまってます。
versionは0.11のJPHPMailerをUTF-8で使用しています。
よろしくお願いします。
function encodeSubjectMimeHeader($string,$charset=null,$linefeed=”\n”){
のように$linefeedを”\n”にするとひとまず解決しました。
環境によってはMTA側で\n→\r\nにされ、また、
\r\nは→\r\r\nにされるって記事を見かけましたが、
それが原因だったのでしょうか。
いつも活用させていただいています。
画像を添付してもThunderbirdのメーラでは
ファイルは無事届くものの、
画像として認識してくれないので調べてみたら
デフォルトではMimeTypeは["application/octet-stream"]になって
いるので['image/jpeg']にしないとだめなんですね。
$mail->addAttachment($filePath,’img.jpg’,'base64′,’image/jpeg’);
まだ仕事に必要かどうかはわかりませんが、PHPの勉強をしていて、メール送信部分でここにたどり着きました。
わかりやすかった上に、簡単にHTMLメールが送信できたので喜んでいました。
ありがとうございました。
しかし、HTML文章中に画像がついている場合は画像が表示されないんですね。
またいろいろなところを検索してがんばりたいと思います。
大変参考にさせていただきました。
おかげさまで添付ファイル付きメールを送信するプログラムを実装することができました。
ありがとうございます。
お役に立てて良かったです!
このblogはとてもひつよですからこのblogの英語ぶぶんをほしです。えいごでこのblogはありますか。
私も同じような目的で、JPHPMailerと同じような派生クラスを昨日作ったところでした。。。
件名等でmb_encode_mimeheaderを使い、74 文字を越えて文字化けしていたところで引っ掛かり、ここにたどり着きました。
とてもとても参考になりました。
助かります・・・。
本当にありがとうございます。
すいません。一点だけ、お時間あったら伺いたいのですが、
>>$mail->From = $from など、プロパティに値を 直接入れたくない (しかも一文字目が大文字)
とあります。「1文字目が大文字」というのはよろしくないのでしょうか?
理由をご教授いただけたら幸いです。
お役にたててよかったです!
「1文字目が大文字」というのはコーディング規約によると思いますが、
あまり一般的ではないように思います・・・^^;
プロパティ名は全部小文字のものが多いかと思います。