WordPress 留言資料表 wp_comments 儲存留言者 Email。本文提供安全、高效的查詢腳本、去重匯出 CSV、大量郵件發送策略 (避免被封)、GDPR 合規提醒,並說明為何不建議直接使用原文的 mysql_* 與字串拼接方式。
<?php
// export-comment-emails.php
// 用法:php export-comment-emails.php > emails.csv
require_once __DIR__ . '/wp-load.php'; // 載入 WordPress 環境
global $wpdb;
// 1. 參數化查詢:去重、排除管理員、僅核准留言
$sql = "
SELECT DISTINCT comment_author_email
FROM {$wpdb->comments}
WHERE comment_approved = '1'
AND comment_type = ''
AND comment_author_email NOT LIKE '%@example.com' -- 排除測試域
AND comment_author_email != ''
ORDER BY comment_author_email
";
$emails = $wpdb->get_col($sql); // 直接回傳單欄陣列
// 2. 基本驗證與清理
$validEmails = array_filter($emails, function($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
});
// 3. 輸出 CSV (標準輸出)
$out = fopen('php://stdout', 'w');
fputcsv($out, ['email']); // 標題列
foreach ($validEmails as $email) {
fputcsv($out, [$email]);
}
fclose($out);
// 錯誤輸出至 stderr
fwrite(STDERR, "Exported " . count($validEmails) . " unique emails.\n");
function exportEmailsChunked(int $chunkSize = 1000): Generator
{
global $wpdb;
$offset = 0;
do {
$sql = $wpdb->prepare("
SELECT DISTINCT comment_author_email
FROM {$wpdb->comments}
WHERE comment_approved = '1' AND comment_type = ''
ORDER BY comment_author_email
LIMIT %d OFFSET %d
", $chunkSize, $offset);
$chunk = $wpdb->get_col($sql);
if (empty($chunk)) break;
foreach ($chunk as $email) {
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
yield $email;
}
}
$offset += $chunkSize;
} while (count($chunk) === $chunkSize);
}
// 使用
$out = fopen('emails.csv', 'w');
fputcsv($out, ['email']);
foreach (exportEmailsChunked() as $email) {
fputcsv($out, [$email]);
}
fclose($out);
| 策略 | 說明 | 工具/服務 |
|---|---|---|
| 使用交易郵件服務商 | 專業 IP 信譽、退信處理、開啟追蹤 | SendGrid, Mailgun, Amazon SES, Postmark |
| 自建 SMTP + 信譽預熱 | 需配置 SPF、DKIM、DMARC、rDNS、IP 預熱 | Postfix + 監控 |
| 分批發送、間隔控制 | 每小時不超過提供商限制,加入隨機延遲 | 佇列系統 (Redis + Worker) |
| 清單清洗 | 移除硬退信、投訴、無效格式、角色帳號 | ZeroBounce, NeverBounce, 自建驗證 |
| 單發而非群發 (BCC) | 每封郵件獨立 To,個性化內容,降低垃圾分數 | 郵件模板引擎 |
| 退信/投訴自動處理 | Webhook 接收退信事件,自動加入抑制清單 | 服務商提供 |
直接操作資料庫雖快,但繞過 WordPress 核心可能導致快取不一致、外掛鉤子未觸發。建議優先使用 WP_Comment_Query 或 $wpdb 並遵循 WordPress 編碼標準,郵件發送務必接入專業服務商,切勿自建 SMTP 除非有專業運維團隊。