Zend PHP 認證考試中,電子郵件處理主要涵蓋:
mail() 函式進階用法與限制<?php
// 錯誤:直接串接使用者輸入,標頭注入風險
$headers = "From: $_POST[email]\r\n";
mail($to, $subject, $body, $headers);
// 正確:驗證並清理輸入
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
if ($email) {
$headers = "From: $email\r\n";
$headers .= "Reply-To: $email\r\n";
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
mail($to, $subject, $body, $headers);
}
?>
解析:mail() 第 4 參數直接插入標頭,未過濾換行符會導致標頭注入攻擊。必須驗證 Email 格式,移除 \r\n。
<?php
$boundary = md5(time());
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/alternative; boundary=\"$boundary\"\r\n";
$message = "--$boundary\r\n";
$message .= "Content-Type: text/plain; charset=UTF-8\r\n\r\n";
$message .= "純文字內容給不支援 HTML 的郵件客戶端\r\n\r\n";
$message .= "--$boundary\r\n";
$message .= "Content-Type: text/html; charset=UTF-8\r\n\r\n";
$message .= "<html><body><h1>HTML 內容</h1></body></html>\r\n\r\n";
$message .= "--$boundary--";
mail($to, '=?UTF-8?B?' . base64_encode('主旨') . '?=', $message, $headers);
?>
解析:multipart/alternative 讓客戶端自動選擇最佳顯示格式。主旨需 RFC 2047 編碼 (Base64 或 Quoted-Printable)。
答案要點:
mail() 依賴本地 MTA (sendmail/postfix),配置複雜、可靠性低mail() 同步阻塞嚴重影響效能<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = 'smtp.example.com';
$mail->SMTPAuth = true;
$mail->Username = 'user@example.com';
$mail->Password = 'secret';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
$mail->setFrom('noreply@example.com', '系統通知');
$mail->addAddress('user@domain.com');
$mail->Subject = 'UTF-8 主旨測試';
$mail->Body = '<h1>HTML 內容</h1>';
$mail->AltBody = '純文字替代內容';
$mail->CharSet = 'UTF-8';
$mail->send();
} catch (Exception $e) {
error_log("郵件發送失敗: {$mail->ErrorInfo}");
}
?>