【问题标题】:How to send email attachments in PHP如何在 PHP 中发送电子邮件附件
【发布时间】:2010-12-02 15:55:25
【问题描述】:
  <?php
  // array with filenames to be sent as attachment
  $files = array("sendFiles.php");

  // email fields: to, from, subject, and so on
  $to = "dfjdsoj@googlemail.com";
  $from = "mail@mail.com";
  $subject ="My subject";
  $message = "A logo has been sen't by". $_SESSION['loggedin_business_name'];
  $headers = "From: $from";

  // boundary 
  $semi_rand = md5(time()); 
  $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";

  // headers for attachment
  $headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\"";

  // multipart boundary
  $message = "This is a multi-part message in MIME format.\n\n" . "--{$mime_boundary}\n" . "Content-Type: text/plain; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" . $message . "\n\n";
  $message .= "--{$mime_boundary}\n";

  // preparing attachments
  for($x=0;$x<count($files);$x++){
      $file = fopen($files[$x],"rb");
      $data = fread($file,filesize($files[$x]));
      fclose($file);
      $data = chunk_split(base64_encode($data));
      $message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$files[$x]\"\n" .
      "Content-Disposition: attachment;\n" . " filename=\"$files[$x]\"\n" .
      "Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
      $message .= "--{$mime_boundary}\n";       
  }

  // send       
  echo sizeof($files);
  $ok = @mail($to, $subject, $message, $headers);
  if ($ok) {
      echo "<p>mail sent to $to!</p>";
  } else {
      echo "<p>mail could not be sent!</p>";
  }
  ?>

我收到一封电子邮件,其中包含我的 sendfiles.php,然后是一个文本文件 ATT00424.txt。数字每次都在变化。发到我的gmail就可以了!很奇怪!


$files = array("sendFiles.php");

  // email fields: to, from, subject, and so on

  $to = "hdfiuhufsadhfu@yaho.com";

  $from = "mail@mail.com";

  $subject ="My subject";

  $message = "A logo has been sen't by". $_POST['loggedin_business_name'];

  $headers = "From: $from";

  // boundary

  $semi_rand = md5(time());

  $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";

// headers for attachment

  $headers .= "\r\nMIME-Version: 1.0\r\n" . "Content-Type: multipart/mixed;\r\n" . " boundary=\"{$mime_boundary}\"";
  // multipart boundary

  $message = "This is a multi-part message in MIME format.\r\n" . "--{$mime_boundary}\r\n" . "Content-Type: text/plain; charset=\"iso-8859-1\"\r\n" . "Content-Transfer-Encoding: 7bit\r\n" . $message . "\r\n";

  $message .= "--{$mime_boundary}\r\n";
  // preparing attachments

  for($x=0;$x<count($files);$x++){

      $file = fopen($files[$x],"rb");

      $data = fread($file,filesize($files[$x]));

      fclose($file);

      $data = chunk_split(base64_encode($data));

      $message .= "Content-Type: {\"application/octet-stream\"};\r\n" . " name=\"$files[$x]\"\r\n" .

      "Content-Disposition: attachment;\r\n" . " filename=\"$files[$x]\"\r\n" .

      "Content-Transfer-Encoding: base64\r\n" . $data . "\r\n";

      $message .= "--{$mime_boundary}\r\n";

  }

在代码中添加 CRLF 修复了附件问题,但现在“未发送徽标”消息已消失。这是为什么呢?

【问题讨论】:

    标签: php


    【解决方案1】:

    Use phpMailer()

    <?php 
    require_once('phpmailer.php');
    
    $mail = new PHPMailer(true); // the true param means it will throw exceptions on errors, which we need to catch
    $mail->IsSendmail(); // telling the class to use SendMail transport
    
    try {
        $mail->AddReplyTo('email@example.com', 'First Last');
        $mail->AddAddress('John@example.com', 'John Doe');
    
        $mail->SetFrom('email@example.com', 'First Last');
        $mail->Subject  =  "Subject Line";
        $mail->AltBody    = "Alternate Text"; // optional, comment out and test
    
        $mail->WordWrap     =   50; // set word wrap    
        $mail->Body = "This is the body of the email";
        $mail->IsHTML(true); // send as HTML
    
        // Single or Multiple File Attachments
        $mail->AddAttachment('../path-to-file.pdf', 'File-Name.pdf');
        $mail->Send(); // Try to send email
        //echo "Message Sent OK<p></p>\n";
        } catch (phpmailerException $e) {
            echo $e->errorMessage(); //Pretty error messages from PHPMailer
        } catch (Exception $e) {
            echo $e->getMessage(); //Boring error messages from anything else!
    }
    // end try
    
    
    ?>
    

    【讨论】:

      【解决方案2】:

      尝试使用 CRLF (\r\n) 换行符。 Outlook 对这些事情可能有点好笑。

      【讨论】:

      • 我同意,这可能是你的问题。
      【解决方案3】:

      你可以使用这个类

      <?php   
      
      /*   
      Usage   
      =====   
          set $this->to
          set $this->subject
          set $this->message (with html tags)
          set $this->from (Optional)
          set $this->cc (this can be an array or a variable) (Optional)
          set $this->bcc (this can be an array or a variable) (Optional)
          set $this->reply_to (Optional)
          set $this->return_path (Optional)
          set $this->x_mailer (Optional)
          set $this->attach_file_name (this can be an array or a variable) (Optional)
      
          $this->SendMail();
      
      This function returns an array of 2 elements which e[0] = true (on success) or false and e[1] = message
      */
      
      class EMail
      {
          var $to;
          var $from;
          var $cc;
          var $bcc;
          var $reply_to;
          var $return_path;
          var $x_mailer;
          var $subject;
          var $message;
          var $attach_file_name;
      
          function EMail()
          {
              $this->to = "";
              $this->subject = "";
              $this->message = "";
              $this->from = "Administrator <admin@" . $_SERVER['SERVER_NAME'] . ">";
              $this->cc = "";
              $this->bcc = "";
              $this->reply_to = $this->from;
              $this->return_path = $this->from;
              $this->x_mailer = "PHP v" . phpversion();
              $this->attach_file_name = "";
          }
      
          function makeFileName ($url)
          {
              $pos=true;
              $PrePos=0;
              while (!$pos==false)
              {
                  $pos = strpos($url,'\\',$PrePos);
                  if ($pos===false)
                  {
                      $temp = substr($url,$PrePos);
                  }
                  else
                  {
                      $PrePos = $pos + 1;
                  }
              }
              return $temp;
          }
      
          function processAttachment()
          {
              if(is_array($this->attach_file_name))
              {
                  $s = sizeof($this->attach_file_name);
                  for($i=0; $i<$s; $i++)
                  {
                      if($this->attach_file_name[$i] != "")
                      {
                          $handle = fopen($this->attach_file_name[$i], 'rb');
                          $file_contents = fread($handle, filesize($this->attach_file_name[$i]));
                          $Attach['contents'][$i] = chunk_split(base64_encode($file_contents));
                          fclose($handle);
                          $Attach['file_name'][$i] = $this->makeFileName ($this->attach_file_name[$i]);
                          $pos=true;
                          $PrePos=0;
                          while (!$pos==false)
                          {
                              $pos = strpos($this->attach_file_name[$i], '.', $PrePos);
                              if ($pos===false)
                              {
                                  $Attach['file_type'][$i] = substr($this->attach_file_name[$i], $PrePos);
                              }
                              else
                              {
                                  $PrePos = $pos+1;
                              }
                          }
                      }
                  }
                  return $Attach;
              }
              else
              {
                  $handle = fopen($this->attach_file_name, 'rb');
                  $file_contents = fread($handle, filesize($this->attach_file_name));
                  $Attach['contents'][0] = chunk_split(base64_encode($file_contents));
                  fclose($handle);
                  $Attach['file_name'][0] = $this->makeFileName ($this->attach_file_name);
                  $pos=true;
                  $PrePos=0;
                  while (!$pos==false)
                  {
                      $pos = strpos($this->attach_file_name, '.', $PrePos);
                      if ($pos===false)
                      {
                          $Attach['file_type'][0] = substr($this->attach_file_name, $PrePos);
                      }
                      else
                      {
                          $PrePos = $pos+1;
                      }
                  }
              }
              return $Attach;
          }
      
          function validateMailAddress($MAddress)
          {
              if (eregi("@", $MAddress) && eregi(".", $MAddress))
              {
                  return true;
              }
              else
              {
                  return false;
              }
          }
      
          function Validate()
          {
              if(is_array($this->to))
              {
                  $msg[0] = false;
                  $msg[1] = "You should provide only one receiver email address";
                  return $msg;
              }
              if(is_array($this->from))
              {
                  $msg[0] = false;
                  $msg[1] = "You should provide only one sender email address";
                  return $msg;
              }
              if($this->to == "")
              {
                  $msg[0] = false;
                  $msg[1] = "You should provide a receiver email address";
                  return $msg;
              }
              if($this->subject == "")
              {
                  $msg[0] = false;
                  $msg[1] = "You should provide a subject for your email";
                  return $msg;
              }
              if($this->message == "")
              {
                  $msg[0] = false;
                  $msg[1] = "You should provide message for your email";
                  return $msg;
              }
              if(!$this->validateMailAddress($this->to))
              {
                  $msg[0] = false;
                  $msg[1] = "Receiver E-Mail Address is not valid";
                  return $msg;
              }
              if(!$this->validateMailAddress($this->from))
              {
                  $msg[0] = false;
                  $msg[1] = "Sender E-Mail Address is not valid";
                  return $msg;
              }
              if(is_array($this->cc))
              {
                  $s = sizeof($this->cc);
                  for($i=0; $i<$s; $i++)
                  {
                      if(!$this->validateMailAddress($this->cc[$i]) && $this->cc[$i] != "")
                      {
                          $msg[0] = false;
                          $msg[1] = $this->cc[$i] . " is not a valid E-Mail Address";
                          return $msg;
                      }
                  }
              }
              else
              {
                  if(!$this->validateMailAddress($this->cc) && $this->cc[$i] != "")
                  {
                      $msg[0] = false;
                      $msg[1] = "CC E-Mail Address is not valid";
                      return $msg;
                  }
              }
              if(is_array($this->bcc))
              {
                  $s = sizeof($this->bcc);
                  for($i=0; $i<$s; $i++)
                  {
                      if(!$this->validateMailAddress($this->bcc[$i]) && $this->bcc[$i] != "")
                      {
                          $msg[0] = false;
                          $msg[1] = $this->bcc[$i] . " is not a valid E-Mail Address";
                          return $msg;
                      }
                  }
              }
              else
              {
                  if(!$this->validateMailAddress($this->bcc) && $this->bcc[$i] != "")
                  {
                      $msg[0] = false;
                      $msg[1] = "BCC E-Mail Address is not valid";
                      return $msg;
                  }
              }
              if(is_array($this->reply_to))
              {
                  $msg[0] = false;
                  $msg[1] = "You should provide only one Reply-to address";
                  return $msg;
              }
              else
              {
                  if(!$this->validateMailAddress($this->reply_to))
                  {
                      $msg[0] = false;
                      $msg[1] = "Reply-to E-Mail Address is not valid";
                      return $msg;
                  }
              }
              if(is_array($this->return_path))
              {
                  $msg[0] = false;
                  $msg[1] = "You should provide only one Return-Path address";
                  return $msg;
              }
              else
              {
                  if(!$this->validateMailAddress($this->return_path))
                  {
                      $msg[0] = false;
                      $msg[1] = "Return-Path E-Mail Address is not valid";
                      return $msg;
                  }
              }
              $msg[0] = true;
              return $msg;
          }
      
          function SendMail()
          {
              $mess = $this->Validate();
              if(!$mess[0])
              {
                  return $mess;
              }
      
              # Common Headers
              $headers  = "From: " . $this->from . "\r\n";
              $headers .= "To: <" . $this->to . ">\r\n";
      
              if(is_array($this->cc))
              {
                  $headers .= "Cc: " . implode(", ", $this->cc) . "\r\n";
              }
              else
              {
                  if($this->cc != "")
                      $headers .= "Cc: " . $this->cc . "\r\n";
              }
      
              if(is_array($this->bcc))
              {
                  $headers .= "BCc: " . implode(", ", $this->bcc) . "\r\n";
              }
              else
              {
                  if($this->bcc != "")
                      $headers .= "BCc: " . $this->bcc . "\r\n";
              }
      
              // these two to set reply address
              $headers .= "Reply-To: " . $this->reply_to . "\r\n";
              $headers .= "Return-Path: " . $this->return_path . "\r\n";
      
              // these two to help avoid spam-filters
              $headers .= "Message-ID: <message-on " . date("d-m-Y h:i:s A") . "@".$_SERVER['SERVER_NAME'].">\r\n";
              $headers .= "X-Mailer: " . $this->x_mailer . "\r\n";
              $headers .= "MIME-Version: 1.0\r\n";
      
              # Tell the E-Mail client to look for multiple parts or chunks
              $headers .= "Content-type: multipart/mixed; boundary=AttachMail0123456\r\n";
      
              # Message Starts here
              $msg  = "--AttachMail0123456\r\n";
      
              $msg .= "Content-type: multipart/alternative; boundary=AttachMail7890123\r\n\r\n";
              $msg .= "--AttachMail7890123\r\n";
      
              $msg .= "Content-Type: text/plain; charset=iso-8859-1\r\n";
              $msg .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n";
      
              $msg .= strip_tags($this->message) . "\r\n";
      
              $msg .= "--AttachMail7890123\r\n";
      
              $msg .= "Content-Type: text/html; charset=iso-8859-1\r\n";
              $msg .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n";
      
              $msg .= "<html><head></head><body>" . $this->message . "</body></html>\r\n";
      
              $msg .= "--AttachMail7890123--\r\n";
      
      
              if($this->attach_file_name != "" || is_array($this->attach_file_name))
              {
                  $Attach = $this->processAttachment();
      
                  $s = sizeof($Attach['file_name']);
                  for($i=0; $i<$s; $i++)
                  {
                      # Start of Attachment chunk
                      $msg .= "--AttachMail0123456\r\n";
      
                      if ($Attach['file_type'][$i]=="gif")
                      {
                          $msg .= "Content-Type: image/gif; name=" . $Attach['file_name'][$i] . "\r\n";
                      }
                      elseif ($Attach['file_type'][$i]=="jpg" || $Attach['file_type'][$i]=="jpeg")
                      {
                          $msg .= "Content-Type: image/jpeg; name=" . $Attach['file_name'][$i] . "\r\n";
                      }
                      else
                      {
                          $msg .= "Content-Type: application/file; name=" . $Attach['file_name'][$i] . "\r\n";
                      }
      
                      $msg .= "Content-Transfer-Encoding: base64\r\n";
                      $msg .= "Content-Disposition: attachment; filename=" . $Attach['file_name'][$i] . "\r\n\r\n";
      
                      $msg .= $Attach['contents'][$i] . "\r\n";
                  }
              }
      
              $msg .= "--AttachMail0123456--";
      
              $result = mail($this->to, $this->subject, $msg, $headers);
              if ($result)
              {
                  $mess[0] = true;
                  $mess[1] = "Mail Successfully delivered";
              }
              else
              {
                  $mess[0] = false;       
                  $mess[1] = "Mail can not be send this time. Please try latter.";
              }
              return $mess;
          }
      }
      ?>
      

      【讨论】:

        【解决方案4】:
        $from = stripslashes("from@demo.com");
        $to = stripslashes("to@to.com");
        $subject =$_POST['subject'];  
        $message = $_POST['mailbody'];  
        
        // Temporary paths of selected files  
        $file1 = $_FILES['file1']['tmp_name'];  
        $file2 = $_FILES['file2']['tmp_name'];  
        $file3 = $_FILES['file3']['tmp_name'];  
        
        // File names of selected files  
        $filename1 = $_FILES['file1']['name'];  
        $filename2 = $_FILES['file2']['name'];  
        $filename3 = $_FILES['file3']['name'];  
        
        // array of filenames to be as attachments  
        $files = array($file1, $file2, $file3);  
        $filenames = array($filename1, $filename2, $filename3);  
        
        // include the from email in the headers  
        $headers = "From: $from";  
        
        // boundary  
        $time = md5(time());  
        $boundary = "==Multipart_Boundary_x{$time}x";  
        
        // headers used for send attachment with email  
        $headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$boundary}\"";  
        
        // multipart boundary  
        $message = "--{$boundary}\n" . "Content-Type: text/plain; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" . $message . "\n\n";  
        $message .= "--{$boundary}\n";  
        
        // attach the attachments to the message  
        for($x = 0; $x < count($files); $x++){
        
            if($files[$x] != ""){
        
                $file = fopen($files[$x],"r");  
                $content = fread($file,filesize($files[$x]));  
                fclose($file);  
                $content = chunk_split(base64_encode($content));  
                $message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$files[$x]\"\n" . "Content-Disposition: attachment;\n" . " filename=\"$filenames[$x]\"\n" . "Content-Transfer-Encoding: base64\n\n" . $content . "\n\n";  
                $message .= "--{$boundary}\n";
            }
        }  
        
        // sending mail  
        $sendmail = mail($to, $subject, $message, $headers);
        

        【讨论】:

          【解决方案5】:

          据我了解,Outlook 在收到混合编码部分的邮件时会创建 ATT12345.txt 附件。如果在编码(或新的 MIME 部分)更改后无法转换邮件的其余部分,它会将其余部分转储到带有您所看到的通用名称的附件中。似乎 Gmail 比 Outlook 更好地处理格式(不足为奇)。

          我不是 Outlook 专家(从不接触这个东西),但看起来this answer on SO 可能会有所帮助(检查你的 $mime_boundary 变量,看最后一部分后面的尾随“--”)。

          【讨论】:

            猜你喜欢
            • 2014-04-12
            • 1970-01-01
            • 2021-03-06
            相关资源
            最近更新 更多