ファイル添付フォームメール

 既にKOMONETの方では公開・配布しているんですが、なかなかこちらで解説ページをアップする暇がなくてごめんなさい。ようやくコード内容を解説する機会ができました。どうぞご覧下さい。

 通常のメーラーなどでは、ファイルを添付してメールを送信することが結構あると思います。画像ファイルやワードファイルなと、何でも添付して相手に送れます。とっても便利ですね。

*注意…このスクリプトはPHP4.2.0以降のスーパーグローバル変数に対応したものになっています。

ファイル構成

 このスクリプトは通常のHTMLページからフォームメール・スクリプトを呼び出して、一旦確認画面を表示後メールを送信するタイプです。ファイル構成は以下の通りです。

komomail.htm・・・メール送信用HTMLページ

komomail.php・・・メール送信用PHPスクリプト

 ここでは、メール送信用PHPスクリプトの内容のみを解説します。HTMLページについてはブラウザ上で下のサンプルページのソースを表示してご覧下さい。

[注意]このスクリプトは、文字コード変換に関してはPHPの自動変換機能に任せていますので、Turbolinux以外のLinuxディストリビューションの場合(特に基本文字コードがeucJPでない場合)、送信メールの内容に文字化けの可能性があります。その場合は、送信前の文字コード変換処理が必要です。ご注意下さい。

<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-sjis">
<TITLE>KOMOメール</TITLE>
<STYLE TYPE="text/css">
<!--
:link {
Color : blue ;
Text-Decoration : None
}
:active {
Color : blue ;
Text-Decoration : None
}
:visited {
Color : blue ;
Text-Decoration : None
}
A:hover {
Color : blue ;
Text-Decoration : Underline
}
-->
</STYLE>
</HEAD>
<BODY BGCOLOR="#FFFBF0">
<CENTER>
<P><IMG SRC="title.gif" WIDTH="244" HEIGHT="69" ALIGN="BOTTOM" BORDER="0"></P>
通常のHTMLによるページの先頭部分です。解説は要りませんね(^^ゞ
<?php
//=====================初期設定======================
$to = "komochan@komonet.ne.jp";
$subject = "From Komomail Sample Script";
$boundary = md5(uniqid(rand())); //バウンダリー文字(パートの境界)
//===================================================
定番の初期設定部分です。
変数
$boundaryはメールの記事部分と添付ファイル部分との境界を示す文字列です。 

★string md5 ( string str )関数・・・文字列のmd5ハッシュ値を計算します。
★string uniqid ( string prefix [ , boolean lcg ] )関数・・・ユニークなIDを生成します。uniqid( )は、ミリ秒単位の現在時刻に基づき、引数prefix で指定された文字列を先頭に付けたユニークなIDを返します。
★int rand ( [ int min [ , int max ] ] )関数・・・乱数を生成します。オプションの引数min, max を省略してコールした場合、rand( )は0とRAND_MAXの間の擬似乱数を返します。使用する前にsrand( )により乱数生成器を初期化する必要があります。

md5(uniqid(rand( )))」の組み合わせにより、推測が困難でより優れたユニークなIDを生成します。
$php_v = PHP_VERSION; //PHPバージョンの取得
if($php_v > "4.1.0"){ //スーパーグローバル変数対応なら
 $PHP_SELF = $_SERVER["PHP_SELF"];
 //フォームデータの取得
 $action = $_POST['action'];
 $name = $_POST['name'];
 $email = $_POST['email'];
 $hp = $_POST['hp'];
 $area = $_POST['area'];
 $tel = $_POST['tel'];
 $comment = $_POST['comment'];
 $upfile = $_FILES['upfile']['tmp_name'];
 $upfile_name = $_FILES['upfile']['name'];
 $upfile_type = $_FILES['upfile']['type'];
}
PHPのバージョン情報を取得し、スーパーグローバル変数対応なら、各変数の値を取得します。
//確認画面を生成
if($action == "post"){
 if($name && $email){
  //ここから書き込みデータの調整
  $name = htmlspecialchars($name); //特殊文字のHTMLエントリへの変換
  $email = htmlspecialchars($email);
  $hp = htmlspecialchars($hp);
  $comment = htmlspecialchars($comment);
  $comment = nl2br($comment); //HTML改行文字の挿入
  $comment = str_replace("\r", "", $comment);
  $comment = str_replace("\n", "", $comment);
  //確認ページを生成
  echo "▼メッセージ確認(送信先: $to )▼<br>\n";
  echo "<TABLE BORDER=1 CELLSPACING=0 WIDTH=80%>\n";
  echo "<FORM ACTION=$PHP_SELF METHOD=POST ENCTYPE=multipart/form-data>\n";
  echo "<INPUT TYPE=HIDDEN NAME=action VALUE=send>\n";
  echo "<TR><TD WIDTH=30%>お名前</TD><TD WIDTH=70%>$name</TD></TR>\n";
  echo "<INPUT TYPE=HIDDEN NAME=name VALUE=\"$name\">\n";
  echo "<TR><TD WIDTH=30%>E-mail</TD><TD WIDTH=70%>$email</TD></TR>\n";
  echo "<INPUT TYPE=HIDDEN NAME=email VALUE=\"$email\">\n";
  if($hp){
   echo "<TR><TD WIDTH=30%>HomePage</TD><TD WIDTH=70%>$hp</TD></TR>\n";
   echo "<INPUT TYPE=HIDDEN NAME=hp VALUE=\"$hp\">\n";
  }
  echo "<TR><TD WIDTH=30%>住んでる地域</TD><TD WIDTH=70%>$area</TD></TR>\n";
  echo "<INPUT TYPE=HIDDEN NAME=area VALUE=$area>\n";
  if($tel){
   echo "<TR><TD WIDTH=30%>お電話</TD><TD WIDTH=70%>$tel</TD></TR>\n";
   echo "<INPUT TYPE=HIDDEN NAME=tel VALUE=\"$tel\">\n";
  }
  if($comment){
   echo "<TR><TD WIDTH=30%>ご意見</TD><TD WIDTH=70%>$comment</TD></TR>\n";
   echo "<INPUT TYPE=HIDDEN NAME=comment VALUE=\"$comment\">\n";
  }
  echo "<TR><TD WIDTH=30%>添付ファイル</TD><TD WIDTH=70%><INPUT TYPE=file NAME=upfile SIZE=35 VALUE=\"$upfile\"></TD></TR>\n";
  echo "</TABLE><br>\n";
  echo "<INPUT TYPE=SUBMIT NAME=Submit VALUE=送信する></FORM>\n";
 }else{
  echo "必須項目が書き込まれていません。やり直して下さい_(._.)_<br><br>\n";
  echo "<INPUT type=button name=close value=閉じる onclick=window.close()>\n";
 }
HTMLページから送信されたデータを受けて、一旦確認ページを表示します。

最初に書き込みデータの調整をしていますが、これは掲示板などでお馴染みの処理ですね(^.^)

後は通常のフォーム生成ですが、注意しなくてはいけないのは、ファイルをアップロードしなくてはいけないので、フォームの
ENCTYPEは「multipart/form-data」となります。
}elseif($action == "send"){
 //メッセージ送信
 $msg = "";
 $from = $email;
 $header = "From: $from\n";
 $header .= "Reply-To: $from\n";
 $header .= "X-Mailer: PHP/".phpversion()."\n";
 $header .= "MIME-version: 1.0\n";
 if(file_exists($upfile)){ //アップファイルがあれば
  $header .= "Content-Type: multipart/mixed;\n";
  $header .= "\tboundary=\"$boundary\"\n";
  $msg .= "This is a multi-part message in MIME format.\n\n";
  $msg .= "--$boundary\n";
  $msg .= "Content-Type: text/plain; charset=ISO-2022-JP\n";
  $msg .= "Content-Transfer-Encoding: 7bit\n\n";
 }else{
  $header .= "Content-Type: text/plain; charset=ISO-2022-JP\n";
  $header .= "Content-Transfer-Encoding: 7bit\n";
 }
 $msg .= "お名前 = $name\n";
 $msg .= "E-mail = $email\n";
 if($hp){ $msg .= "HomePage = $hp\n"; }
 if($area){ $msg .= "住んでる地域 = $area\n"; }
 if($tel){ $msg .= "お電話 = $tel\n"; }
 if($comment){
  $comment = str_replace("<br />", "\n", $comment);
  $msg .= "ご意見 = $comment\n";
 }
 if(file_exists($upfile)){
  $fp = fopen($upfile, "r") or die("error"); //ファイルの読み込み
  $contents = fread($fp, filesize($upfile));
  fclose($fp);
  $f_encoded = chunk_split(base64_encode($contents)); //エンコードして分割
  $msg .= "\n\n--$boundary\n";
  $msg .= "Content-Type: " . $upfile_type . ";\n";
  $msg .= "\tname=\"$upfile_name\"\n";
  $msg .= "Content-Transfer-Encoding: base64\n";
  $msg .= "Content-Disposition: attachment;\n";
  $msg .= "\tfilename=\"$upfile_name\"\n\n";
  $msg .= "$f_encoded\n";
  $msg .= "--$boundary--";
 }
 if(mail($to, $subject, $msg, $header)){ //ファイル添付に対応
  echo "メールが正常に送信されました(^o^)丿<br><br>\n";
  echo "<INPUT type=button name=close value=閉じる onclick=window.close()>\n";
 }else{
  echo "メールの送信に失敗しました(>_<)もう一度やり直して下さい。<br><br>\n";
  echo "<INPUT type=button name=close value=閉じる onclick=window.close()>\n";
 }
}
?>
メッセージの送信処理です。

添付ファイルがある場合とない場合とで、コード処理を分けています。

添付ファイルがある場合は、記事と添付ファイルとの間に、パートの境界となるバウンダリー文字列を挿入します。

ファイル添付タイプなので、メール送信にはマルチバイト文字対応の
mb_send_mail( )関数は使えませんので、mail( )関数を使っています。

★void die ( string message )関数・・・引数message で渡したメッセージを出力し、スクリプトの処理を終了します。この関数の戻り値はありません。

★string chunk_split ( string string [ , int chunklen [ , string end ] ] )関数・・・文字列をより小さな部分に分割する際に使用されます。引数chunklen (デフォルトは76)文字ごとに文字列end (デフォルトは"\r\n")を挿入します。変換前の元の文字列はそのままとし、変換後の新しい文字列を返します。

★string base64_encode ( string data )関数・・・base64_encode( )は、data をBase64方式でエンコードします。Base64でエンコードされたデータは、エンコード前のデータに比べて33%よけいに記憶容量を必要とします。

[Base64]
 電子メールに画像などのバイナリデータを添付する際に、中身を文字列(テキスト)データに置換(エンコード)する方式の一つ。メールにはテキストデータしか載せられない為、画像や音声、ワープロ文書などのバイナリファイルは、そのままでは送受信できない。この為、送信時に一定のルールに従ってデータを文字に置換し、受信後に元のデータに復元(デコード)するという手法が取られるようになった。この置換ルールの1つがBASE64である。インターネット上の電子メールでは、このBASE64を用いるのが標準的である。

[エンコード]

データを一定の規則に基づいて符号化すること。エンコードを行なうソフトウェアをエンコーダという。データの圧縮や暗号化などがこれにあたる。エンコードされたデータを元に戻すことを
デコードという。
</CENTER>
</BODY>
</HTML>
ページの終了部分です。

 添付ファイルの数を2つ以上にしたい場合は、KOMONETサイトで無料配布しているスクリプトのソースをご参照下さい。

 *上の内容をこのまま複写しても動きません。何故なら、表示を見やすくする為コード中に全角スペースが入っているからです。実際にお使いになる時は、この点を修正してからサーバにアップして下さい。

HOME