帝国CMS 留言板表单提交自动触发邮件通知

帝国CMS 留言板表单提交自动触发邮件通知


Backend
EmpireCMS PHP SMTP

环境与账号准备

默认的发信模块兼容性容易出问题,建议走 SSL 465 端口。 右上角设置>账户与安全>安全设置>生成授权码 image.png

  1. 获取授权码:去 QQ 邮箱或网易邮箱后台开启 SMTP 服务,生成的授权码就是发信密码,不是网页登录密码。
  2. 开启 OpenSSL:PHP 必须开启 OpenSSL 扩展,否则 465 端口无法建立安全连接。
    • 在服务器环境(如宝塔)打开 PHP 设置。
    • 编辑 php.ini 配置文件。
    • 搜索 openssl,删除前面的分号。
    • 保存并重启 PHP 服务。 image.png

核心发信逻辑实现

/e/class/ 目录下新建一个独立的发信脚本 SendEmail.inc.php。采用 Socket 方式直接与 SMTP 服务器通信,不依赖第三方库。

<?php
if(!defined('InEmpireCMS')) { exit(); }

/**
 * 帝国CMS 独立发信函数 (兼容 SSL 465)
 */
function EcmsToSendMail($to_email, $subject, $body) {
    global $empire, $dbtbpre;

    // 1. 读取系统后台配置
    $pr = $empire->fetch1("select smtphost, smtpport, fromemail, emailusername, emailpassword, emailname from {$dbtbpre}enewspublic limit 1");
    if(!$pr['smtphost']) return false;

    // 2. 参数初始化
    $host = "ssl://" . $pr['smtphost']; 
    $port = $pr['smtpport'] ? $pr['smtpport'] : 465;
    $user = $pr['emailusername'];
    $pass = $pr['emailpassword']; 
    $from = $pr['fromemail'];
    $name = $pr['emailname'];

    // 3. 建立连接
    $fp = @fsockopen($host, $port, $errno, $errstr, 30);
    if (!$fp) return false;

    fgets($fp, 512);

    // 4. SMTP 握手与鉴权
    fputs($fp, "EHLO " . $_SERVER['HTTP_HOST'] . "\r\n");
    while($line = fgets($fp, 512)) { if(substr($line, 3, 1) == ' ') break; } 

    fputs($fp, "AUTH LOGIN\r\n");
    fgets($fp, 512);
    fputs($fp, base64_encode($user) . "\r\n");
    fgets($fp, 512);
    fputs($fp, base64_encode($pass) . "\r\n");
    $res = fgets($fp, 512);

    if(strpos($res, '235') === false) { fclose($fp); return false; }

    fputs($fp, "MAIL FROM: <$from>\r\n");
    fgets($fp, 512);

    $to_emails = is_array($to_email) ? $to_email : explode(',', $to_email);
    foreach($to_emails as $rcpt) {
        $rcpt = trim($rcpt);
        if($rcpt) {
            fputs($fp, "RCPT TO: <$rcpt>\r\n");
            fgets($fp, 512);
        }
    }

    fputs($fp, "DATA\r\n");
    fgets($fp, 512);

    // 5. 组装邮件头 (强制 UTF-8 编码)
    $headers  = "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/html; charset=utf-8\r\n";
    $headers .= "Content-Transfer-Encoding: base64\r\n";
    $headers .= "From: =?UTF-8?B?".base64_encode($name)."?= <$from>\r\n";
    $headers .= "Subject: =?UTF-8?B?".base64_encode($subject)."?=\r\n";
    $headers .= "Date: " . date("r") . "\r\n\r\n";

    $content = chunk_split(base64_encode($body));

    fputs($fp, $headers . $content . "\r\n.\r\n");
    $res = fgets($fp, 512);

    fputs($fp, "QUIT\r\n");
    fclose($fp);

    return (strpos($res, '250') !== false);
}
?>

植入发信触发器

将发信函数挂载到反馈表单的处理逻辑中。

定位文件:/e/class/q_functions.php

搜索函数:function AddFeedback

插入位置:找到 $reurl=DoingReturnUrl(... 这一行,在该行之前插入逻辑。

// ========== 邮件通知模块开始 ==========
// 1. 引入发信逻辑
@include_once(ECMS_PATH.'e/class/SendEmail.inc.php');

// 2. 构建邮件内容 (直接读取表单提交的 $add 数组)
$mail_title = "【新客户留言】" . $add['title']; 
$mail_content = "<b>姓名:</b>" . $add['name'] . "<br>" .
                "<b>邮箱:</b>" . $add['email'] . "<br>" .
                "<b>内容:</b>" . $add['saytext'] . "<br>" .
                "<b>提交时间:</b>" . date("Y-m-d H:i:s");

// 3. 指定管理员接收邮箱
$admin_email = "[email protected]"; 

// 4. 执行发信
EcmsToSendMail($admin_email, $mail_title, $mail_content);
// ========== 邮件通知模块结束 ==========

注意事项

  • 端口冲突:如果服务器开启了防火墙,确保 465 端口的出站流量未被拦截。
  • 字段对应:代码中的 $add['name'] 等字段必须与你在后台定义的反馈插件字段名一致。
  • 防弹机制:使用 @include_once 引入是为了防止发信脚本缺失导致整个表单提交流程崩溃。
© 2026 Personal Website
Developed by Ryan 🫡