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

CodeIgniter 整合 PHPMailer 發送郵件:Helper 封裝與配置最佳實踐

     編輯:PHP 相關知識

目錄結構規劃


application/
├── config/
│   └── email.php          # 郵件配置文件
├── helpers/
│   └── email_helper.php   # 封裝發送函數
├── libraries/
│   └── PHPMailer/         # PHPMailer 庫文件
│       ├── class.phpmailer.php
│       ├── class.smtp.php
│       └── class.pop3.php

配置文件 application/config/email.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

$config['mail_protocol']  = 'smtp';
$config['mail_smtp_host'] = 'smtp.21cn.com';
$config['mail_smtp_port'] = 25;           // 465 (SSL) / 587 (TLS)
$config['mail_smtp_user'] = 'xxxx@21cn.com';
$config['mail_smtp_pass'] = 'your_password';
$config['mail_from_email'] = 'xxxx@21cn.com';
$config['mail_from_name']  = '焦常雲';
$config['mail_charset']    = 'UTF-8';
$config['mail_mailtype']   = 'html';
$config['mail_newline']    = "\r\n";
$config['mail_smtp_crypto'] = '';         // 'ssl' 或 'tls'
$config['mail_smtp_timeout'] = 30;

Helper 封裝 application/helpers/email_helper.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

if (!function_exists('send_email')) {
    /**
     * 發送郵件統一入口
     * @param string|array $to      收件人,支持單個或多個
     * @param string       $subject 主題
     * @param string       $message 內容(HTML)
     * @param array        $options 附加選項:cc, bcc, attachments 等
     * @return bool
     */
    function send_email($to, $subject, $message, $options = []) {
        $CI =& get_instance();
        
        // 載入配置
        $CI->config->load('email', TRUE);
        $cfg = $CI->config->item('email');
        
        // 載入 PHPMailer
        require_once APPPATH . 'libraries/PHPMailer/class.phpmailer.php';
        require_once APPPATH . 'libraries/PHPMailer/class.smtp.php';
        
        $mail = new PHPMailer(true); // 啟用異常拋出
        
        try {
            // 基礎設置
            $mail->isSMTP();
            $mail->Host       = $cfg['mail_smtp_host'];
            $mail->Port       = $cfg['mail_smtp_port'];
            $mail->SMTPAuth   = true;
            $mail->Username   = $cfg['mail_smtp_user'];
            $mail->Password   = $cfg['mail_smtp_pass'];
            $mail->CharSet    = $cfg['mail_charset'];
            $mail->Encoding   = 'base64';
            
            // 加密協議
            if (!empty($cfg['mail_smtp_crypto'])) {
                $mail->SMTPSecure = $cfg['mail_smtp_crypto'];
            }
            
            // 超時設置
            $mail->Timeout = $cfg['mail_smtp_timeout'];
            
            // 發件人
            $mail->setFrom($cfg['mail_from_email'], $cfg['mail_from_name']);
            
            // 收件人
            $recipients = is_array($to) ? $to : [$to];
            foreach ($recipients as $recipient) {
                $mail->addAddress($recipient);
            }
            
            // 抄送/密送
            if (!empty($options['cc'])) {
                foreach ((array)$options['cc'] as $cc) $mail->addCC($cc);
            }
            if (!empty($options['bcc'])) {
                foreach ((array)$options['bcc'] as $bcc) $mail->addBCC($bcc);
            }
            
            // 附件
            if (!empty($options['attachments'])) {
                foreach ((array)$options['attachments'] as $attachment) {
                    if (is_array($attachment)) {
                        $mail->addAttachment($attachment['path'], $attachment['name'] ?? '');
                    } else {
                        $mail->addAttachment($attachment);
                    }
                }
            }
            
            // 郵件內容
            $mail->isHTML($cfg['mail_mailtype'] === 'html');
            $mail->Subject = $subject;
            $mail->Body    = $message;
            $mail->AltBody = strip_tags($message); // 純文本備選
            
            // 發送
            $mail->send();
            log_message('info', "Email sent to: " . implode(',', $recipients));
            return true;
            
        } catch (phpmailerException $e) {
            log_message('error', "PHPMailer Error: " . $e->errorMessage());
        } catch (Exception $e) {
            log_message('error', "Email Send Error: " . $e->getMessage());
        }
        
        return false;
    }
}

控制器中調用示例

<?php
class Welcome extends CI_Controller {
    public function test_email() {
        $this->load->helper('email');
        
        $result = send_email(
            'user@example.com',
            '測試郵件主題',
            '

你好!

這是一封HTML測試郵件。

', [ 'cc' => 'admin@example.com', 'attachments' => [ ['path' => FCPATH . 'uploads/report.pdf', 'name' => '月報.pdf'], ] ] ); echo $result ? '發送成功' : '發送失敗,請查看日誌'; } }

進階優化建議

1. 異步發送(推薦生產環境)


// 將郵件任務推送到隊列
function queue_email($to, $subject, $message, $options = []) {
    $CI =& get_instance();
    $CI->load->library('queue'); // 假設使用 Redis/RabbitMQ 隊列庫
    $CI->queue->push('email_job', compact('to', 'subject', 'message', 'options'));
}

// Worker 處理
class EmailJob {
    public function perform($data) {
        send_email($data['to'], $data['subject'], $data['message'], $data['options']);
    }
}

2. 模板引擎整合


function send_template_email($to, $template, $data, $subject) {
    $CI =& get_instance();
    $message = $CI->load->view('emails/' . $template, $data, TRUE);
    return send_email($to, $subject, $message);
}

// 視圖文件:application/views/emails/welcome.php
// 

歡迎 !

3. 發送記錄與重試機制


// 數據庫表:email_logs (to, subject, status, attempts, last_error, created_at)
// 發送前寫入記錄,失敗時更新 attempts 和 last_error,定時任務重試 attempts < 3 的記錄

常見問題排查

錯誤現象排查方向
SMTP connect() failed主機/端口錯誤、防火牆攔截、SSL/TLS 協議不匹配
Authentication failed賬號密碼錯誤、需開啟「客戶端授權碼」(如 QQ 郵箱、Gmail)
中文亂碼CharSet 未設置 UTF-8、Subject 需用 mb_encode_mimeheader
大附件發送失敗調整 PHP memory_limit、post_max_size、SMTP 服務商限制

安全提醒

  • 配置文件含敏感密碼,**絕不可提交到版本庫**,使用 .env 或環境變量注入
  • 生產環境強制使用 TLS 加密(端口 465/587 + SMTPSecure = 'tls')
  • 限制發送頻率,防止被判定為垃圾郵件發送源
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved