PHP电子邮件附件的问题

时间:2014-08-19 19:12:16

标签: php email-attachments

我有这个PHP代码,它发送一封带有附件的电子邮件以及传递的表单值(我删除了这一部分以便于阅读)。该代码有效,但如果用户未选择附件,则会将空白文本文件作为附件提交。

如果没有选择附件,有没有办法让它不附加任何东西?

PHP:

<?php

//if there is post
if(isset($_POST) && !empty($_POST) ) {
  // if thre is an attachment
  $_FILES['attachment']['name'];
  // store some variables
  $file_name = $_FILES['attachment']['name'];
  $temp_name = $_FILES['attachment']['tmp_name'];
  $file_type = $_FILES['attachment']['type'];

  // get the extension of the file
  $base = basename($file_name);
  $extension = substr($base, strlen($base)-4, strlen($base));

  // only allow these file types
  $allowed_extensions = array(".doc", "docx", ".pdf", ".zip", ".csv", ".xls", "xlsx", "");

  // check that this file type is allowed
  if(in_array($extension,$allowed_extensions)) {

    // mail essentials
    $from = $_POST['email'];

    // multiple recipients
    $to  = 'email@email.com,'.$_POST['email'];

    // subject
    $today_day=date("d") ;
    $today_month=date("m") ;
    $today_year=date("Y") ;

    $subject = 'Confirmation: '
             . " Date and Time: ".$_POST['ScheduledMonth']."/".$_POST['ScheduledDay']."/". $_POST['ScheduledYear']
             . ' at '. $_POST['ScheduledHour'].":".$_POST['ScheduledMin']." ".$_POST['AMPM']." ".$_POST['TimeZone'];

    // message
    $message = 'HTML message goes here';

    // things you need
    $file = $temp_name;
    $content = chunk_split(base64_encode(file_get_contents($file)));
    $uid = md5(uniqid(time()));

    //standard mail headers
    $header = "From: ".$from."\r\n";
    $header .= "Reply-To: ".$replyto."\r\n";
    $header .= "MIME-Version: 1.0\r\n";

    // declaring we have multiple parts of email (i.e plain text and attachment)
    $header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
    $header .= "This is a multi-part message in MIME format.\r\n";

    // text part
    $header .= "--".$uid."\r\n";
    $header .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
    $header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
    $header .= $message."\r\n\r\n";

    // file attachment
    $header .= "--".$uid."\r\n";
    $header .= "Content-Type: ".$file_type."; name=\"".$file_name."\"\r\n";
    $header .= "Content-Transfer-Encoding: base64\r\n";
    $header .= "Content-Disposition: attachment filename=\"".$file_name."\"\r\n\r\n";
    $header .= $content."\r\n\r\n";

    //send the mail
    if (mail($to, $subject, "", $header)) {
      //redirect to the thank you page
      header('Location: http://www.somesite.com/thankyou.php');
    } else {
      echo "Fail";
    }

  } else {
    echo "file type not allowed";
  }

}
?>

1 个答案:

答案 0 :(得分:1)

答案

您可能使用其中一条评论中提到的电子邮件库,但如果您必须使用mail(),则您的代码应如下所示:

//standard mail headers
$header  = "From: $from\r\n";
$header .= "Reply-To: $replyto\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"$uid\"\r\n\r\n";

停在那儿!双换行符(\r\n\r\n)标记标题的结尾。我不知道mail()是否允许你像这样发送身体。也许是这样,但你的其他信息应该放在消息 body

你也错过了close-delimiter。请参阅下面的MIME语法部分。

$body  = "This is a multi-part message in MIME format.\r\n";

// text part
$body .= "--$uid\r\n"; // dash-boundary
$body .= "Content-type: text/html; charset=iso-8859-1\r\n";
$body .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$body .= $message;

// file attachment
if (isset ($FILES['attachment'])) {
  $file_name = $_FILES['attachment']['name'];
  $temp_name = $_FILES['attachment']['tmp_name'];
  $file_type = $_FILES['attachment']['type'];
  $body .= "\r\n--$uid\r\n"; // delimiter
  $body .= "Content-Type: $file_type; name=\"$file_name\"\r\n";
  $body .= "Content-Transfer-Encoding: base64\r\n";
  $body .= "Content-Disposition: attachment filename=\"$file_name\"\r\n\r\n";
  $body .= $content;
}
$body .= "\r\n--$uid--\r\n"; // close-delimiter

//send the mail
if (mail($to, $subject, $body, $header)) {
  /* ... */

附加说明

$from = $_POST['email'];
$to  = 'email@email.com,'.$_POST['email'];

$header = "From: ".$from."\r\n";
$header .= "Reply-To: ".$replyto."\r\n";

if (mail($to, $subject, "", $header)) {

上面的代码允许用户通过$to变量和$from变量(通过插入换行符和{{1})将垃圾邮件或其他不需要的电子邮件发送到任意地址标题或类似的)。您应该从Bcc:移除$_POST['email'],并从$to中删除换行符。我不知道你的$from标题; Reply-To:未定义。


$replyto

此代码不执行任何操作(如果没有附件,则可能会生成通知)。


// if thre is an attachment
$_FILES['attachment']['name'];

这可以简化为:

$extension = substr($base, strlen($base)-4, strlen($base));

MIME语法

根据RFC 2046,这是多部分消息体结构的摘录。(BNF语法略有简化。)

multipart-body := [preamble CRLF]
                  dash-boundary CRLF
                  body-part *encapsulation
                  close-delimiter
                  [CRLF epilogue]

dash-boundary := "--" boundary

body-part := MIME-part-headers [CRLF *OCTET]

encapsulation := delimiter
                 CRLF body-part

delimiter := CRLF dash-boundary

close-delimiter := delimiter "--"

参考