duannuci4008 2014-08-19 19:12
浏览 57
已采纳

PHP电子邮件附件的问题

I have this PHP code which sends an email with an attachment along with form values that get passed through (I removed this section to make it easier to read). The code works but it submits a blank text file as an attachment if the user does not select an attachment.

Is there any way to have it just not attach anything if no attachment is selected?

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."
";
    $header .= "Reply-To: ".$replyto."
";
    $header .= "MIME-Version: 1.0
";

    // declaring we have multiple parts of email (i.e plain text and attachment)
    $header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"

";
    $header .= "This is a multi-part message in MIME format.
";

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

";
    $header .= $message."

";

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

";
    $header .= $content."

";

    //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条回答 默认 最新

  • duanpuqi9965 2014-08-19 22:22
    关注

    Answer

    You propably should use an email library as was mentioned in one of the comments, but if you must use mail(), your code should look something like this:

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

    Stop right there! The double line-break ( ) marks the end of the headers. I don't know if mail() allows you to send the body like this. Perhaps it does, but the rest of your message should go inside the message body.

    You're also missing a close-delimiter. See the MIME syntax section below.

    $body  = "This is a multi-part message in MIME format.
    ";
    
    // text part
    $body .= "--$uid
    "; // dash-boundary
    $body .= "Content-type: text/html; charset=iso-8859-1
    ";
    $body .= "Content-Transfer-Encoding: 7bit
    
    ";
    $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 .= "
    --$uid
    "; // delimiter
      $body .= "Content-Type: $file_type; name=\"$file_name\"
    ";
      $body .= "Content-Transfer-Encoding: base64
    ";
      $body .= "Content-Disposition: attachment filename=\"$file_name\"
    
    ";
      $body .= $content;
    }
    $body .= "
    --$uid--
    "; // close-delimiter
    
    //send the mail
    if (mail($to, $subject, $body, $header)) {
      /* ... */
    

    Additional notes

    $from = $_POST['email'];
    $to  = 'email@email.com,'.$_POST['email'];
    
    $header = "From: ".$from."
    ";
    $header .= "Reply-To: ".$replyto."
    ";
    
    if (mail($to, $subject, "", $header)) {
    

    The code above allows the user to send spam or other unwanted email to arbitrary addresses, both through the $to variable and through the $from variable (by inserting line-breaks and a Bcc: header or similar). You should remove $_POST['email'] from $to, and strip out line-breaks from $from. I don't know about your Reply-To: header; $replyto is undefined.


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

    This code does nothing (except perhaps generate a notice if there is no attachment).


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

    This can be simplified as:

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

    MIME Syntax

    This is an excerpt of what the structure of a multi-part message body looks like according to RFC 2046. (BNF syntax, somewhat simplified.)

    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 "--"
    

    References

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥35 平滑拟合曲线该如何生成
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站