首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 微信公眾平台開發:預約表單提交後發送 Email 通知的完整實作

     編輯:PHP 綜合知識

微信公眾號常見需求:使用者預約試駕、報名活動、提交維修單後,**即時發送 Email 通知商家/客服**。本文基於 YYUC 框架(原生 PHP 亦可直接套用),示範從表單接收、資料庫查詢通知設定、SMTP 發送到錯誤處理的完整流程。

架構圖

[微信用戶] → 提交預約表單 → [PHP 控制器] → 寫入資料庫
                                    ↓
                            查詢商家通知設定 (Email、開關)
                                    ↓
                            SMTP 發送郵件 → [商家郵箱]

1. 框架整合:載入郵件元件

// yyuc/yyuc.php 或 common/bootstrap.php
require_once YYUC_LIB . 'plugin/SendMail.php';
$sendMail = new SendMail(); // 全域可用,或註冊到容器

2. 郵件設定檔(支援多場景模板)

// wx/conf.php
public static $email = [
    'reg' => [
        'protocol'  => 'smtp',
        'smtp_host' => 'smtp.qq.com',
        'smtp_port' => 465, // SSL
        'smtp_user' => 'notify@example.com',
        'smtp_pass' => 'auth_code_or_password',
        'from'      => ['notify@example.com', '預約系統通知'],
        'charset'   => 'utf-8',
        'ssl'       => true,
    ],
    'findpwd' => [ /* ... */ ],
];

3. 控制器:預約提交後發送通知

// wx/controller/AppointmentController.php
public function submit()
{
    $wid = Session::get('wid'); // 微信公眾號 ID
    $openid = Session::get('openid');

    // 1. 驗證並寫入預約單
    $data = $this->validateAndSave($this->input->post());
    if (!$data['success']) return $this->ajaxReturn($data);

    // 2. 取得商家通知設定
    $pubs = new Model('pubs');
    $pubs->field('uid')->find(['id' => $wid]);
    $merchantUid = $pubs->uid;

    $merchant = new Model('micro_car_yysj'); // 商家擴展表
    $merchant->field('noticeemailon, noticeemail')->find(['uid' => $merchantUid]);

    // 3. 開關開啟且有郵箱 → 發送
    if ($merchant->noticeemailon == '1' && !empty($merchant->noticeemail)) {
        $subject = '新預約通知';
        $body = "您好,有新的預約單:\n"
              . "用戶:$openid\n"
              . "項目:{$data['item_name']}\n"
              . "時間:{$data['appoint_time']}\n"
              . "請登入後台查看詳情:https://example.com/admin/appointment/{$data['id']}";

        $result = $sendMail->normal_send(
            'reg',                    // 使用 reg 設定
            $merchant->noticeemail,   // 收件人
            $subject,
            $body
        );

        if (!$result) {
            // 記錄日誌,不阻斷主流程
            log_write('email_failed', "Appointment {$data['id']} notify failed: " . $sendMail->error);
        }
    }

    return $this->ajaxReturn(['success' => true, 'msg' => '預約成功']);
}

4. SendMail 類別關鍵方法(簡化版)

class SendMail {
    public $error = '';

    public function normal_send(string $tpl, string $to, string $subject, string $body): bool
    {
        $cfg = Config::get("email.$tpl");
        if (!$cfg) { $this->error = "郵件模板 $tpl 不存在"; return false; }

        // 使用 PHPMailer 或內建 mail(),此處示意 PHPMailer
        $mail = new PHPMailer(true);
        try {
            $mail->isSMTP();
            $mail->Host       = $cfg['smtp_host'];
            $mail->Port       = $cfg['smtp_port'] ?? 25;
            $mail->SMTPAuth   = true;
            $mail->Username   = $cfg['smtp_user'];
            $mail->Password   = $cfg['smtp_pass'];
            $mail->SMTPSecure = $cfg['ssl'] ? 'ssl' : 'tls';
            $mail->CharSet    = $cfg['charset'] ?? 'utf-8';

            $mail->setFrom(...$cfg['from']);
            $mail->addAddress($to);
            $mail->Subject = $subject;
            $mail->Body    = $body;
            $mail->isHTML(false); // 純文字,或 true 送 HTML

            $mail->send();
            return true;
        } catch (Exception $e) {
            $this->error = $e->getMessage();
            return false;
        }
    }
}

5. 關鍵優化與防禦

風險對策
SMTP 發送阻塞請求(2~5 秒)**非同步發送**:寫入 email_queue 表,CLI Worker 輪詢發送;或用 fastcgi_finish_request() 先回應用戶再發送。
郵件被判定垃圾郵件設定 SPF/DKIM/DMARC、使用企業郵箱、內容避免敏感詞、HTML/文字雙版本。
發送失敗無感知記錄 email_log 表(狀態、重試次數、錯誤訊息),定時重試 + 管理員告警。
高併發連接數耗盡SMTP 連接池複用、限制並發數、考慮第三方郵件服務。

非同步發送最小實作(fastcgi_finish_request)

// 控制器結束前
$response = ['success' => true];
$this->ajaxReturn($response); // 先輸出 JSON
fastcgi_finish_request();     // 關閉連線,用戶收到回應

// 後續在同進程繼續執行(不阻塞用戶)
if ($needNotify) {
    $sendMail->normal_send('reg', $email, $subject, $body);
    // 記錄日誌...
}

將郵件通知從「同步阻塞」升級為「非同步可靠佇列」,並配合完整的設定管理、日誌審計、重試機制,即可構建企業級微信公眾號預約通知系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved