帝国CMS 留言板表单提交自动触发邮件通知
Backend
EmpireCMS PHP SMTP 环境与账号准备
默认的发信模块兼容性容易出问题,建议走 SSL 465 端口。
右上角设置>账户与安全>安全设置>生成授权码

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

核心发信逻辑实现
在 /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引入是为了防止发信脚本缺失导致整个表单提交流程崩溃。