• 締切済み

PHP Windows版のmail()を使用して添付ファイルを送りたい

はじめて、質問させていただきます。 環境はWindowsXP(Pro)+IIS+PHPです。 PHPのmail()関数を使用して、添付ファイルをメールで送信したいと考えております。 mail("-----@co.jp",$subject,$msg,$headers);を実行します。 $headersは、追加ヘッダということになっています。 $boundary="-*-*-*-*-*-*-*-*-*-Boundary_".uniqid("b"); とセットし、 $headersには、 $headers=Content-Type:multipart/mixed; $headers.=boundary=$boundary; として、実行します。 送られてきたメールのヘッダの内容を確認すると 「Content-Type」が、 Content-Type:text/plain; となってしまいます。 mail()関数のヘッダの指定方法は、これでいいのでしょうか? 実際のコードは、メッセージ部分などいろいろ書き込んでいます。いろいろ書き換えて実験してみましたが、どうも、この問題をクリアできないと添付ファイルメールを送信することができないようです。 ご存知の方があれば、教えていただきたいです。 よろしくお願いいたします。

みんなの回答

  • elf2000
  • ベストアンサー率50% (6/12)
回答No.5

ざっくり添付関連の処理を書き直してみるのはいかがでしょうか? 参考URLにPEAR::Mail_mimeを用いた添付の実装サンプルがあります. 最後にPEAR::Mailを使用していますが,内部でmail()を使用する実装なので最終的には等価の処理になるかと思います. #ソースを読めば分かるのですが,mb_send_mail()はmail()のラッパーではありません.

参考URL:
http://wiki.poyo.jp/read/PHP/tips/mail/attach
Komattades
質問者

補足

ご回答ありがとうございます。あきらめかけていたので。。。とりあえず試してみます。 結果はまたご報告させていただきます。

  • kusukusu
  • ベストアンサー率38% (141/363)
回答No.4

うーん…(^^;お手上げですね… 私の環境ではこれで上手く動きます。 私の環境はLinuxで、Windows環境での開発はしたことありませんが、その違いかもしれません。 それももう一つ違うのが、mail関数ではなくmb_send_mail関数を私用しています。 でもmb_send_mail関数はただのmail関数のラッパーなので、違いはないと思うのですが…

Komattades
質問者

補足

ありがとうございます。 Windowsというのが、影響しているように思っています。 mb_send_mailでもトライしてみます。

  • kusukusu
  • ベストアンサー率38% (141/363)
回答No.3

以下は、私が随分前に書いたメール送信クラスのヘッダーを作るメンバ関数です。 Komattadesさんがやりたいこととだいぶ重複すると思いますので、参考にしてみてください。 function make_header($subject,$mes,$attach) { //$attach=array(array("リアルファイルの場所","ファイル名"),…) //添付ファイルがあれば、Boundary……をヘッダに書き込む if($attach!="") { $boundary="-*-*-*-*-*-*-*-*-Boundary_".uniqid("b"); } $subject=mb_convert_encoding($subject,"JIS","auto"); $mes=mb_convert_encoding($mes,"JIS","auto"); //通常ヘッダ $mail_header ="Return-Path: <".$this->myaddress.">\n"; $mail_header .="From: ".mb_convert_encoding($this->user_name,"JIS","auto")."<".$this->myaddress.">\n"; $mail_header .="Date: ".date("r")."\n"; if($this->reply_to!="") { $mail_header .="Reply-To: ".mb_convert_encoding($this->user_name,"JIS","auto")."<".$this->reply_to.">\n"; } $mail_header .="X-Mailer: ".$this->xmailer."\n"; $mail_header .="MIME-Version: 1.0\n"; //添付ファイルがあればマルチパートをヘッダに書き込む if(sizeof($attach)!=0) { $mail_header .="Content-Type: Multipart/Mixed; boundary=\"".$boundary."\"\n"; $mail_header .="--".$boundary."\n"; $mail_header .="Content-Type: text/plain; charset=\"ISO-2022-JP\"\n"; $mail_header .="Content-Transfer-Encoding: 7bit\n\n"; } //添付ファイルがあればコンテントタイプをヘッダに書き込む for($i=0;$i<sizeof($attach);++$i) { $file=$attach[$i][0]; $filename=$attach[$i][1]; $mail_header .="--".$boundary."\n"; $mail_header .="Content-Type: application/octet-stream; name=\"".$filename."\"\n"; $mail_header .="Content-Transfer-Encoding: base64\n"; $mail_header .="Content-Disposition: attachment; filename=\"".$filename."\"\n\n"; $mail_header .=chunk_split(base64_encode($file))."\n"; } if(sizeof($attach)!=0) { $mail_header .="--".$boundary."\n"; } //メール本文 return $mail_header; }

Komattades
質問者

補足

教えていただいたようにやってみましたが、同じような現象が起き、うまくいきません。 この関数自体は、得ようとした結果を作ることができています。 メールを送信する際に、以下のようにしています。 mail("aaaaa@bb.co.jp",$subject,$test,$mail_headers); "aaaaa@bb.co.jp"は、送信先メールアドレス $subjectは、サブジェクト $testは、メール本文 $mail_headersは、教えていただいたmake_header関数の戻り値 実際に送られてきたメールのソースを見ると、 make_header関数の戻り値の後に、$testの内容が追加されていて、この$testの内容の最後の3byteがない状態の文字列が、実際の添付ファイルの内容となっています。すごく不思議です。 mail関数の使い方が間違っているのでしょうか? 前の方法でも同じような現象が起こっていました。 違うのは、前はmail関数のヘッダ部分のContent-Typeを Content-Type: Multipart/Mixed; としても、送られてきたメールでは、勝手にtext/plainとなってしまっていました。今は、確実にMultipart/Mixedとなります。 何かありましたら、お教えください。 よろしくお願いいたします。

  • kusukusu
  • ベストアンサー率38% (141/363)
回答No.2

ざっと見た感じ、おかしな箇所が2箇所あります。 まず > //添付ファイル > $msg.="--$boundary\n"; > $msg.="Content-Type: text/plain;\n"; ここでtext/plainを指定しています。 せっかくマルチパート指定しているにもかかわらず、添付部分までテキストに指定しているからおかしくなるとおもいます。 Content-Type: application/octet-stream と変更してみてください。 次に > $msg.=base64_encode("abcdefghijklmn")."\n"; base64でエンコードしただけでは、RFCの基準を満たさない場合、訳の分からないデータとなってしまいます。 chunk_split(base64_encode($file)) と、RFCの基準通りの形式に変更してみてください。 他はだいたいいいと思いますが、TYPO等は確認していませんのでその辺りも注意してみてください。

Komattades
質問者

補足

ご回答ありがとうございます。 早速、2箇所のコードを修正してみました。 が、やはり結果のメッセージのヘッダは、 Content-Type: text/plain; charset="iso-2022-jp" となってしまいます。 ファイルは添付されずに、メールの本文に$msgの内容が記述されています。 形式的には、合っているように見えます。 が、ヘッダがtext/plainなので、マルチパートとして認識されずに、すべてそのまま本文に記述されているように見えます。 改行の入れ方などにも、ルールがあるのでしょうか? ご回答いただき、非常に助かっています。 もしも、何か思い当たるところがあれば、お教えいただけるととてもありがたいです。 よろしくお願いいたします。

  • kusukusu
  • ベストアンサー率38% (141/363)
回答No.1

> Content-Type:text/plain; > となってしまいます。 添付ファイルを送りたいとのことですが、そう言う場合はマルチパートで、メール部分と添付部分に分けなければいけません。 で、メール本文部分がtext/plainであるのは当然です。 で、本題ですが、書かれているコードではマルチパート部分の記述がまるでないので、もし本当にこれだけであれば、添付ファイルとならないのは当たり前です。 (マルチパートで区切ってはいるが、そのマルチパートの添付部分について何もコーディングされていない) > 実際のコードは、メッセージ部分などいろいろ書き込んでいます。 添付ファイルの部分はどういった処理をしているのですか? ここに転記する際、省いている可能性もありますので、もっと詳しくコードを書いてください。

Komattades
質問者

補足

すみません。実際のコードでは、マルチパートの部分を書き込んでいます。 //mail $boundary="-*-*-*-*-*-*-*-*-Boundary_".uniqid("b"); $From="*****@***.co.jp"; $To=""*****@***.co.jp"; $subject="test1"; $body="testaaa"; $filename="test.txt"; //メールヘッダ部分 $headers="From: $From\n"; $headers.="To: $To\n"; $headers.="MIME-Version:1.0\n"; $headers.="Content-Type: multipart/mixed;\n"; $headers.="boundary=\"$boundary\"\n"; $msg="This is multi-part message in MIME format.\n\n"; //本文 $msg.="--$boundary\n"; $msg.="Content-Transfer-Encoding:7bit\n"; $msg.="\n"; $msg.="$body\n"; $msg.="\n"; //添付ファイル $msg.="--$boundary\n"; $msg.="Content-Type: text/plain;\n"; $msg.="name=\"$filename\";\n"; $msg.="Content-Transfer-Encoding: base64\n"; $msg.="Content-Disposition: attachment;\n"; $msg.="filename=\"$filename\"\n"; $msg.="\n"; $msg.=base64_encode("abcdefghijklmn")."\n"; $msg.="\n"; $msg.="--$boundary--"; mail($To,$subject,$msg,$headers); となっています。 $headersのところで、multipart/mixedと指定しているにもかかわらず、実際に送られたメールのヘッダはtext/plainになってしまいます。 現在、$headersと$msgに分けていますが、ここで書き込んでいる内容をすべて$headersの中に入れて、 mail($To,$subject,"test",$headers); とすると、添付ファイルの中身が"test"となったメールが送られてきます。 で、そのメールの中身を見てみると、すべてのマルチパートの終わった後に、"test"という文字列が入った内容となっています。 ヘッダ+ boundary=-*-*-*-*-*-*-*-*-Boundary_ ........................... ---*-*-*-*-*-*-*-*-Boundary ........................... -*-*-*-*-*-*-*-*-Boundary_-- test $msgにすべての内容を入れて、 mail($To,$subject,$msg); ともしてみましたが、これだと、すべての内容がメール本文となったメールが送られてきます。 どのような方法ならうまくいくのでしょうか?

関連するQ&A