15. メール送信
今日は、メール送信についてご説明いたします。
■メール送信について
WEBサーバにメールを送信するプログラム(メールエージェントと言います)が
インストールされている場合、Perlからメールを送信することができます。
通常、レンタルサーバなどにはメール送信機能が組み込まれています。
メールエージェントには、SendMailやQMailなどの種類があります。
PHPでは、サーバのPHPの設定により、使用されるメールエージェントが異なり
ます。
■メール送信方法
PHPでのメール送信は非常に簡単です。
-----------------------------------------------------------------
// メールヘッダを作成
$header = 'From: from@test.co.jp';
// 宛先
$mail_to = 'to@test.co.jp';
// 件名
$subject = "件名です";
// 本文
$mail_body = "メール本文です。\n";
// メール送信処理
if (!mb_send_mail($mail_to, $subject, $mail_body, $header)) {
print "メール送信に失敗しました。";
exit;
}
-----------------------------------------------------------------
上記のように、mb_send_mail関数を呼ぶだけです。mb_send_mail関数の引数は、
順番に、宛先、件名、本文、ヘッダになります。メールヘッダは省略可能です。
メールヘッダは、送信者のメールアドレスや、返信先のメールアドレスなどを
記述することで、設定することができます。
メールヘッダを記述する場合は、
From: from@test.co.jp
Reply-To: reply@test.co.jp
と、改行を入れます。
宛先、件名、本文は、省略できません。
メール送信処理に失敗した場合は、mb_send_mailの戻り値でfalseが返ってきます
ので、エラー処理を行ってください。
■メールの文字コードについて
一般的にインターネットに流れているメールは、ほとんどの場合、JISコードという
文字コードが書かれています。そして、WindowsはシフトJIS、UNIXはEUCという
コードが通常使われているため、そのまま送信すると、文字化けしてしまう場合が
あります。
そこで、文字コードを変換するという処理を加える必要があります。
基本的に、mb_send_mail関数を使用すれば、自動的に最適な文字コードで送って
くれるので、文字化けすることはないはずですが、そのまま送ると文字化けする
方が多いので、文字変換を行うようにしてください。
ちなみに、文字コード変換を行わないメール送信は、mail関数があります。この
使い方は、mb_send_mailと全く同じです。
-----------------------------------------------------------------
// JISコードに変換
$subject = mb_convert_encoding($subject, "JIS");
$mail_body = mb_convert_encoding($mail_body, "JIS");
-----------------------------------------------------------------
このように、mb_convert_encoding関数で、JISコードに変換します。上記のように
記述すると、もともとの文字コードがシフトJISでもEUCでも、自動的に判別し、
JISコードに変換してくれます。
ただ、現在の文字コードが分かっている場合は、mb_convert_encodingの3番目の
引数に、現在の文字コードを渡した方が正確に変換してくれます。
現状の文字コードがシフトJISの場合は、以下のようにします。
-----------------------------------------------------------------
// JISコードに変換
$subject = mb_convert_encoding($subject, "JIS", "SJIS");
$mail_body = mb_convert_encoding($mail_body, "JIS", "SJIS");
-----------------------------------------------------------------
★今日のまとめサンプルプログラム
-----------------------------------------------------------------
<HTML>
<BODY>
<?
// メールヘッダ(送信者のメールアドレス)
$header = 'From: from@test.co.jp';
// 宛先のメールアドレス
$mail_to = 'info@searchai.jp';
// 件名
$subject = '件名です';
// 本文
$mail_body = 'テストメッセージです。';
// JISコードへ変換
$subject = mb_convert_encoding($subject, "JIS");
$mail_body = mb_convert_encoding($mail_body, "JIS");
// メール送信処理
if (mb_send_mail($mail_to, $subject, $mail_body, $header)) {
print "メール送信正常に処理しました。";
}
else {
print "メール送信に失敗しました。";
}
?>
</BODY>
</HTML>
-----------------------------------------------------------------
■解説
レッスンの中ででてきたサンプルを少し整理したものです。
始めに送信者、宛先、件名、本文などを準備し、JISコードへの変換を行い、メール
送信処理をしています。
メールの送信結果をHTML上に出力しているので、メール送信に成功したかどうかを
確認できます。
★課題
1. HTML上に、メール送信者(text)、件名(text)、本文(textarea)のフォームを
作成し、POST送信で受け取って、自分のメールアドレスへ送信されるプログラムを
作成してください。
★前回の課題の解答
1. 簡易的な掲示板を作成してください。
→下のサンプルを参照してください。
-----------------------------------------------------------------
<?
// データファイル
$file_name = './dengon.txt';
// 最大件数
$msmax = 20;
// クッキー名a
$cknm = 'bbs';
// 掲示板ファイル読み込み
$rec_in = file($file_name);
// 投稿処理開始
if ($_POST["md"] == '1')
{
// データチェック
$r_hd = $_POST["hd"];
$r_hd = str_replace(" ", " ", $r_hd);
$r_hd = str_replace("<", "<", $r_hd);
$r_hd = str_replace(">", ">", $r_hd);
$r_ms = $_POST["ms"];
$r_ms = str_replace(" ", " ", $r_ms);
$r_ms = str_replace("<", "<", $r_ms);
$r_ms = str_replace(">", ">", $r_ms);
if (!$r_hd)
{
// ハンドルネームが空
exit;
}
if (!$r_ms)
{
// メッセージが空
exit;
}
// 掲示板編集
$dt = localtime(time(), true);
$dt['tm_year'] += 1900;
$dt['tm_mon']++;
$datetime = sprintf("%04d.%02d.%02d %02d:%02d:%02d", $dt['tm_year'], $dt['tm_mon'], $dt['tm_mday'], $dt['tm_hour'], $dt['tm_min'], $dt['tm_sec']);
// 最大ログ数取得
$max = count($rec_in);
if ($max >= $msmax)
{
$max = $msmax - 1;
}
// 書き込み内容編集
for ($iCnt = $max; $iCnt > 0; $iCnt--)
{
$rec_in[$iCnt] = $rec_in[$iCnt - 1];
}
$rec_in[0] = $datetime . '_~|~_' . $hd . '_~|~_' . $ms . "\n";
// 伝言ファイル書き込み
if (!($fno = fopen($file_name, "w")))
{
die;
}
// ファイルロック
flock($fno, LOCK_EX);
foreach($rec_in as $a)
{
fwrite($fno, $a);
}
// ファイルロック解除
flock($fno, LOCK_UN);
fclose($fno);
// 投稿処理終了
}
else
{
$r_hd = $_COOKIE[$cknm];
}
// クッキー設定
setcookie($cknm, $r_hd, time()+60*24*60*60);
?>
<HTML>
<BODY>
<CENTER>
<P><FONT style="font-size=12pt"><B>◆ 簡易掲示版 ◆</B></FONT></P>
<FORM action="<?=$_SERVER["SCRIPT_NAME"]?>" id="FORM1" method="post" name="FORM1">
<INPUT TYPE="hidden" NAME="md" VALUE="1">
<TABLE bgcolor="#b0b0b0" border="0" cellPadding="3" cellSpacing="2">
<TBODY>
<TR bgcolor="#f0f0f0">
<TD nowrap><FONT style="font-size=9pt">ハンドル</FONT></TD>
<TD nowrap><INPUT name="hd" size="22" maxlength="40" value="<?=$r_hd?>">
</TR>
<TR bgcolor="#f0f0f0">
<TD nowrap><FONT style="font-size=9pt">メッセージ</font></TD>
<TD nowrap><INPUT name="ms" size="62" maxlength="200">
</TR>
</TBODY>
</TABLE>
<BR>
<TABLE bgcolor="#b0b0b0" border="0" cellPadding="3" ccllPladding="2">
<TBODY>
<TR bgcolor="f0f0f0">
<TD nowrap><INPUT name="submit1" type="submit" value=" 投稿 "></TD>
<TD nowrap><INPUT name="reset1" type="reset" value="リセット"></TD>
</TR>
</TBODY>
</TABLE>
</FORM>
<?
if (count($rec_in) > 0) {
// 掲示板ファイルヘッド表示
?>
<TABLE bgcolor="#b0b0b0" border="0" cellpadding="3" cellspacing="2">
<TBODY>
<TR bgcolor="#d0d0d0">
<TD nowrap><FONT style="font-size=9pt">日付</FONT></TD>
<TD nowrap><FONT style="font-size=9pt">ハンドル</FONT></TD>
<TD><FONT style="font-size=9pt">メッセージ</FONT></TD>
</TR>
<?
// 掲示板ファイルボディ表示
foreach($rec_in as $a) {
$w = strtok($a, "_~|~_");
$dt = substr($w, 0, 16);
$w = strtok("_~|~_");
// 文字コード変換
$hd = mb_convert_encoding($w, "SJIS", "auto");
$w = strtok("_~|~_");
// 文字コード変換
$ms = mb_convert_encoding($w, "SJIS", "auto");
print '<TR bgcolor=#f0f0f0>';
print '<TD nowrap><FONT style="font-size=9pt">' . $dt . '</FONT></TD>';
print '<TD nowrap><FONT style="font-size=9pt">' . $hd . '</FONT></TD>';
print '<TD><FONT size=-1>' . $ms . '</FONT></TD>';
print '</TR>';
}
// 掲示板ファイルテイル表示
?>
</TBODY>
</TABLE>
<?
}
// HTMLテイル表示
?>
</CENTER>
</BODY>
</HTML>
-----------------------------------------------------------------
■解説
まず、掲示板データファイルを読み込みます。そして、投稿の処理でなければ
クッキーを取得してからHTMLを表示します。
<FORM>のACTIONに$_SERVER['SCRIPT_NAME']を指定していますが、これは環境変数から
現在のファイル名を取り出しますので、自分自身へPOST送信することになります。
<FORM>タグの中にHIDDENの属性で、"md"を 1 として渡し、POSTで"md"に 1 が送られて
きた場合に、ファイルに登録する処理を行っています。
ファイル登録は、ファイルデータ配列の最後に投稿されたデータを追加し、その
配列をファイルに書き込みます。
また、この処理は課題にないですが、最大件数を決め、最大件数を超えると、古い
データが削除されるようにしています。
ファイルの読み込みは、file関数を使用しています。これは、1 行を 1 配列の要素と
して、取り出します。
ファイル書き込み時には、簡易的ではありますが、ファイルロックも行っています。
エラー処理でexitしてしまっていますが、できればエラー処理を関数化して、エラー
メッセージを表示するようにすると良いでしょう。
|