PHP发送带附件邮件类实现与使用指南

远山来客
远山来客
发布时间:2026-10-14 | 2人浏览过
原创

在 PHP 开发中,原生 mail() 函数仅支持纯文本发送。要实现发送带附件邮件,核心在于遵循 MIME 协议,将正文与附件以特定边界符(Boundary)拼接,并对二进制文件进行 Base64 编码。

结果或目标

实现一个通用的 PHP 邮件发送类,能够正确处理包含普通文本和任意二进制附件的复合邮件体,确保收件人能正常查看正文并下载附件。

准备条件

  • 一台运行 PHP 的服务端,且已配置好邮件发送服务(如 Postfix/Sendmail)。

  • 基础的文件读写权限(用于读取本地附件路径)。

真实操作顺序

第1步:构建邮件发送类

定义 CMailFile 类,封装邮件头部信息、MIME 结构生成及文件编码逻辑。该类主要依赖 PHP 的 mail() 函数,因此必须手动处理所有邮件头。

  1. 初始化参数:构造函数接收主题、收件人、发件人、正文、附件路径等必要信息。

  2. 生成 SMTP 头部:通过 write_smtpheaders() 设置 From、Reply-To 等信息,避免被邮件服务器过滤。

  3. 生成 MIME 头部:通过 write_mimeheaders() 声明邮件类型为 multipart/mixed,并指定唯一的 Boundary 分隔符(如 --==================_846811060==_)。

  4. 编码附件:通过 encode_file() 读取本地文件,使用 base64_encode() 进行编码,并用 chunk_split() 添加换行符以适应 MIME 规范。

  5. 组装消息体:分别生成正文块和附件块,通过 Boundary 连接。正文标记为 text/plain,附件标记为 application/octet-stream 或指定类型。

<?php
class CMailFile { 
 
  var $subject;  
  var $addr_to;  
  var $text_body;  
  var $text_encoded;  
  var $mime_headers;  
  var $mime_boundary = "--==================_846811060==_";  
  var $smtp_headers;
   
  function CMailFile($subject,$to,$from,$msg,$filename,$downfilename,$mimetype = "application/octet-stream",$mime_filename = false) {
    $this->subject = $subject;     
    $this->addr_to = $to;     
    $this->smtp_headers = $this->write_smtpheaders($from);
    $this->text_body = $this->write_body($msg); 
    $this->text_encoded = $this->attach_file($filename,$downfilename,$mimetype,$mime_filename); 
    $this->mime_headers = $this->write_mimeheaders($filename, $mime_filename);
  }
  
  function attach_file($filename,$downfilename,$mimetype,$mime_filename) { 
    $encoded = $this->encode_file($filename);
    if ($mime_filename) $filename = $mime_filename;
    $out = "--" . $this->mime_boundary . "\n"; 
    $out = $out . "Content-type: " . $mimetype . "; name=\"$filename\";\n"; 
    $out = $out . "Content-Transfer-Encoding: base64\n"; 
    $out = $out . "Content-disposition: attachment; filename=\"$downfilename\"\n\n"; 
    $out = $out . $encoded . "\n"; 
    $out = $out . "--" . $this->mime_boundary . "--" . "\n"; 
    return $out;
  }

  function encode_file($sourcefile) {
    $encoded = "";
    if (is_readable($sourcefile)) {
      $fd = fopen($sourcefile, "r");
      $contents = fread($fd, filesize($sourcefile));
      $encoded = chunk_split(base64_encode($contents));
      fclose($fd);
    }
    return $encoded;
  }  
  
  function sendfile() {   
    $headers = $this->smtp_headers . $this->mime_headers;
    $message = $this->text_body . $this->text_encoded;
    mail($this->addr_to,$this->subject,$message,$headers);
  }
  
  function write_body($msgtext) {
    $out = "--" . $this->mime_boundary . "\n";
    $out = $out . "Content-Type: text/plain; charset=\"us-ascii\"\n\n";
    $out = $out . $msgtext . "\n";
    return $out;
  }
  
  function write_mimeheaders($filename, $mime_filename) {
    if ($mime_filename) $filename = $mime_filename;
    $out = "MIME-version: 1.0\n";
    $out = $out . "Content-type: multipart/mixed; ";
    $out = $out . "boundary=\"$this->mime_boundary\"\n";
    $out = $out . "Content-transfer-encoding: 7BIT\n";
    $out = $out . "X-attachments: $filename;\n\n";
    return $out;
  }
  
  function write_smtpheaders($addr_from) {
    $out = "From: $addr_from\n";
    $out = $out . "Reply-To: $addr_from\n";
    $out = $out . "X-Mailer: PHP\n";
    $out = $out . "X-Sender: $addr_from\n";
    return $out;
  }
}
?>

第2步:执行邮件发送演示

在实际应用中,只需实例化该类并传入对应参数即可完成发送。注意 Demo 中的变量命名需与实际需求对齐。

<?php
require_once('emailclass.php');

// 邮件基本参数
$subject = "测试附件邮件";
$sendto = 'recipient@example.com'; // 收件人地址
$replyto = 'sender@example.com';   // 发件人/回复地址
$message = "这是一封包含附件的测试邮件。";

// 附件相关参数
$filename = 'test.jpg';             // 本地附件路径
$mimetype = "image/jpeg";           // 附件 MIME 类型
$downloadname = 'my_photo.jpg';     // 下载时显示的文件名

// 实例化并发送
$mailfile = new CMailFile($subject, $sendto, $replyto, $message, $filename, $downloadname, $mimetype);
$mailfile->sendfile();
?>

完成判断

  • 若服务端未拦截邮件,收件箱应收到一封主题为 “测试附件邮件” 的邮件。

  • 邮件正文显示设定的文本内容。

  • 邮件附件栏出现名为 my_photo.jpg 的文件,且大小与本地原始文件一致。

简要总结

以上就是 PHP 实现发送带附件邮件的详细内容,更多关于 PHP 邮件开发的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表