PEAR::Mailを使ってメールを送信してみよう
PHPにはmb_send_mail()関数という日本語を含めたメールを送信する機能がありますがよく文字化けします。PHPの自動エンコーディング機能がうまくいかずに文字化けをするのですが、設定がシビアなので使ってません。例えば、同じサーバーを使っている場合は制作時に気をつければ問題ありませんが、サーバーを移行するようなことがあると新しいサーバーでメールが文字化けしたり結構大変だったりします。
結局send()関数を使うのですが、これで日本語のメールを送信する為には追加メールヘッダを記述する必要があります。mb_send_mail()関数よりはマシですが、これもこれで設定に左右されるので意外と大変。メール送信用の自作関数を作ったものの完璧ではありませんでした。
最終的に落ち着いたのは、PEARのMailです。記述がシンプルな上に自由に設定できて便利。
ということで今回はPEAR::Mailを紹介します。
インストールについて知りたい方は、過去の記事をご参照ください。
レンタルサーバーでPEARを使う方法
WindowsでPEARを自動インストールしてみよう
まずは、基本から以下のソースを見てください。
require_once("Mail.php");$header['From'] = "piyo@s-memo.net";
$mail = Mail::factory("sendmail");
$ret = $mail->send("to@s-memo.net", $header, "メール本文");
if(PEAR::isError($ret)) {
die("エラーメッセージ:".$ret->getMessage());
}
これはタイトルも宛先も空白の必須項目のみを記述したサンプルです。
PEAR::Mailで、必要なのは「From(送信者)」「To(送信先)」「メール本文」の3つです。
1行目はいつも通りMail.phpをインクルードしています。
require_once("Mail.php");
3行目では「From(送信者)」を配列にセットしています。
$header['From'] = "piyo@s-memo.net";
5行目でMail::factory()メーラインスタンスを作成しています。
$mail = Mail::factory("sendmail");
7行目でメールを送信しています。第2引数に3行目で作ったFromをセットしている配列を指定しています。
$ret = $mail->send("to@s-memo.net", $header, "メール本文");
8~10行目はメール送信に失敗した場合に、エラーメッセージを表示させます。
if(PEAR::isError($ret)) {
die("エラーメッセージ:".$ret->getMessage());
}
メールを受信してみると分かるのですが、宛先も件名も空っぽになっています^^;
これだけだと使い道がないので、もう少し実用的なものを作ってみます。
先ほどのスクリプトに赤の部分を追加・修正してください。(メールアドレスは適当に変えてください)
require_once("Mail.php");$header['From'] = "ピヨヒコ<piyo@s-memo.net>";
$header['To'] = "To様<to@s-memo.net>";
$header['Cc'] = "Cc様<cc@s-memo.net>";
$header['Bcc'] = "Bcc様<bcc@s-memo.net>";
$header['Reply-To'] = "piyopiyo@s-memo.net";
$header['Subject'] = "メールのタイトル";$address = array("to@s-memo.net", "cc@s-memo.net", "bcc@s-memo.net");
$mail = Mail::factory("sendmail");
$ret = $mail->send($address, $header, "メール本文");
if(PEAR::isError($ret)) {
die("エラーメッセージ:".$ret->getMessage());
}
$headerの連想配列を追加しました。この連想配列にメールアドレスをセットしても指定のアドレスにはメールは送信されません。この配列はメールを受信した時に表示されるテキストです。(上記の例だとメールを受信した時に送信者に「ピヨヒコ」、宛先に「To様」、Ccに「Cc様」と表示されます)
メールを送信先はsend()メソッドで指定します。最初の例のように直接記述することもできますが、複数のアドレスに送信する場合、配列又はカンマ区切りで指定します。
以下のように配列を作って、
$address = array("to@s-memo.net", "cc@s-memo.net", "bcc@s-memo.net");
send()メソッドから複数アドレスに送信します。
$mail->send($address, $header, "メール本文");
[ちょっと余談]
以下の「Reply-To」というのはメールの返信先です。
$header['Reply-To'] = "piyopiyo@s-memo.net";
Fromは「piyo@s-memo.net」ですが、メーラーから返信をすると宛先に「piyopiyo@s-memo.net」が指定されます。Fromと返信先を変えたい時に使いましょう。
最後にSMTPからメールを送信してみましょう。
SMTPを使用すれば外部のメールアドレスからメールを送信することができます。
先ほどのスクリプトを修正します。赤の部分を追加・修正してください。
require_once("Mail.php");$param['host'] = "smtp.s-memo.net";
$param['port'] = 25;
$param['auth'] = TRUE;
$param['username'] = "piyohiko";
$param['password'] = "password";$header['From'] = "ピヨヒコ<piyo@s-memo.net>";
$header['To'] = "To様<to@s-memo.net>";
$header['Cc'] = "Cc様<cc@s-memo.net>";
$header['Bcc'] = "Bcc様<bcc@s-memo.net>";
$header['Reply-To'] = "piyopiyo@s-memo.net";
$header['Subject'] = "メールのタイトル";$address = array("to@s-memo.net", "cc@s-memo.net", "bcc@s-memo.net");
$mail = Mail::factory("smtp", $param);
$ret = $mail->send($address, $header, "メール本文");
if(PEAR::isError($ret)) {
die("エラーメッセージ:".$ret->getMessage());
}
ホスト名やポート番号等を連想配列を追加しています。
$param['host'] = "smtp.s-memo.net";
$param['port'] = 25;
$param['auth'] = TRUE;
$param['username'] = "piyohiko";
$param['password'] = "password";
「auth」はSMTP認証を使用するかどうかを指定します。TRUEでSMTP認証を使用し、FALSEでSMTP認証を使用しません。
ユーザ名やパスワードはSMTP認証に使用するユーザ名とパスワードを挿入します。
次に制作した連想配列を以下にセットします。
$mail = Mail::factory("smtp", $param);
後はsend()メソッドでメールを送信すれば完了です。
SMTPは外部サーバーのメールを使用できますが、ポートを開いてもらう必要がありますのでご注意ください。
予想以上に長くなりましたが今日はここまで。
と思いましたが、せっかくなのでMailクラスのリファレンスも残しておきます。
Mailクラスのfactoryメソッドのリァレンスは以下の通り
factory($backend, [, $param]);
$backend:「mail」「smtp」「sendmail」のいずれか
$param:パラメータの連想配列(FromやToなど)以下を参照
factoryメソッドの第2引数のパラメータは以下の通り
[「sendmail」の場合]
$p['sendmail_path']:sendmailへのファイルパス /usr/bin/sendmail等
$p['sendmail_args']:sendmailに渡す追加パラメータ
[「smtp」の場合]
$p['host']:SMTPを利用するドメイン又はIP名(デフォルト:localhost)
$p['port']:接続ポート番号(デフォルト:25)
$p['auth']:SMTP認証を使用するかどうか(デフォルト:FALSE)
$p['username'}:SMTP認証のユーザ名
$p['password'}:SMTP認証のパスワード
Mailクラスのsendメソッドのリファレンスは以下の通り
send($address, $header, $msg);
$address:メールアドレス(複数送信は配列又はカンマ区切り)
$header:追加ヘッダの連想配列。詳細は以下を参照
$msg:メール本文
sendメソッドの第2引数のパラメータは以下の通り
$h['From']:送信者
$h['To']:送信先(To)
$h['Cc']:送信先(Cc)
$h['Bcc']:送信先(Bcc)
$h['Reply-To']:メールの返信先
$h['Subject']:メールタイトル
send()メソッドの第2引数に「To」や「Cc」を追加しても実際には送信されません。これはメール受信者の表示用の為の記述です。
実際に送信したい場合は、第1引数に同じアドレスを記述してください。
[関連記事]
・PEAR::Mail_Mimeを使ってHTMLメールを送ってみよう
【雑談】
やっと昼型に戻りました!まあ、いつまでもつか分かりませんが、、、^^;

コメント
ちょうどPEARでメール送信プログラムを作成していて、PHP経験自体が浅いので悩んでいたところととてもわかりやすい内容でした。
助かりました。
ちなみに・・・
宛先アドレスの存在有無っていうのは、Mail::send()の後で判定できたりするんですかね?
投稿者: サル | 2007年04月26日 21:55
コメントありがとうございます。
>宛先アドレスの存在有無っていうのは、Mail::send()の後で判定できたりするんですかね?
そうですね。存在有無の判定とは少し違うのですが、存在しないメールアドレスにメールを送信した場合、エラーになります。
上記のようにMail::send()を使ったとして、「to@s-memo.net」のアドレスが存在しなかった場合、下記のようにエラーメッセージが表示されます。(環境によっては出ないこともあります)
投稿者: Piyohiko | 2007年04月26日 22:43
はじめまして。チャトランといいます。
PHPで送信ページを作ろうと頑張っています。
教えて頂きたいことがございまして、
pearでは、以下のようにサーバ側メーラーのインスタンスを設定しなければならないということですが、クライアント側で契約しているプロバイダのメーラーを使用出来ないのでしょうか?
$mail = Mail::factory("sendmail");
ちゃ
投稿者: チャトラン | 2007年08月16日 11:54
thanks
投稿者: Anonymous | 2007年10月19日 17:05
はじめまして。
mb_send_mail()関数で外部サーバーのメール送信ができず困っておりましたところ、PEAR::Mailを使ったSMTP認証の記事を拝見いたしました。無事、メール送信できました。本当にありがとうございました。
投稿者: きあい | 2008年01月24日 22:16
はじめまして。
PHPから配信されたメールについて、エラーをどのように
拾うか、悩んでいてこのページに辿り着きました。
>存在しないメールアドレスにメールを送信した場合、エラーになります。
これは本当でしょうか?
私の環境では、
-----
$ret=$mail_object->send([存在しないメールアドレス], $headers, $body);
if(PEAR::isError($ret)) {
echo("エラーメッセージ:".$ret->getMessage());
}
-----
でエラーが表示されず(PEAR::isError($ret) が False)、
普通に送信され、
$headers['From'] または $headers['Return-Path'] に
設定されたアドレスにエラーメールが戻ります。
PEARのエラー処理で、何か設定など必要なのでしょうか?
一応、
PEAR::setErrorHandling(PEAR_ERROR_RETURN);
と書いてみたりもしましたが、状況は変わりません。
お心当たりなど、教えて頂けたら大変助かります。
どうぞ、よろしくお願い致します。
投稿者: Iju | 2009年05月26日 16:51
コメントありがとうございます。
>存在しないメールアドレスにメールを送信した場合、エラーになります。
間違いですね・・・ご指摘ありがとうございます。
環境によってはエラーはでません。
メールの送信が終わった後に送信先のメールアドレスが存在せずにメールが戻ってきてると思いますので、PEAR側の問題ではないと思いますが私も確信はありません。。。
力になれず申し訳ありませんm(_ _)m
投稿者: Piyohiko | 2009年05月26日 19:26
念のため書き添えておきます。
>存在しないメールアドレスにメールを送信した場合、エラーになります。
これは多くの場合、間違いです。
PEAR::Mail は、郵便で言うところの「ポストに投函」だけを行います。実際に送信が始まるのは投函されたあとなので、 PEAR::Mail は正しく配送されたかどうかを知ることができません。
このポストというのは通常は自分のサーバにある SMTP なので、自分のドメイン宛のメールに限り PEAR::Mail はエラーを出す場合があります。
投稿者: 通りすがり | 2009年09月22日 06:32
PEAR::Mailについて参考にさせて頂きました。ありがとうございました。もしよろしければ2つほど質問させてください。
$header['From']と$header['To'] についてです。
$header['From']にピヨヒコなどの全角文字を記入するとエラーが起こってしまいます。なにか当方に問題があるのでしょうか?
$header['To'] やCcに全角文字を記入すると(To様など)問題なく送信できますがYahooメールなどで受信すると文字化けしてしまいます(outlookなどでは問題ありません)。
これらの解決方法あれば教えていただけませんか?
投稿者: sk | 2009年09月25日 18:55