
聯絡表單、忘記密碼、新會員通知、新訂單通知、留言通知,WordPress 裡這些信,幾乎都是同一個函式 wp_mail() 寄出去的。
所以只要寄信出問題,所有通知會一起收不到。最常見的情況是:客人打電話來問「表單送出好幾天了,怎麼都沒回?」,這時才發現網站已經好幾個月沒寄出任何一封信。
這篇有 3 段程式碼:
- 後台加一個「寄測試信」的頁面,按一下就知道網站寄不寄得出信
- 寄信失敗時,把原因記下來
- 改用 SMTP(Gmail、公司信箱)寄信
程式碼放在子佈景主題的 functions.php,或用 Code Snippets 這類外掛新增。
WordPress 為什麼會寄不出信
WordPress 預設的寄信方式,是把信交給主機上的寄信程式(PHP 的 mail() 函式)。問題通常出在這裡:
- 主機沒有可以用的寄信程式:很多 VPS、雲端主機沒有安裝,或是主機商把它關掉了。
- 寄出去了,但被當成垃圾信或直接退回:預設的寄件人是
wordpress@你的網域,這個信箱多半不存在;網域的 SPF、DKIM 設定也沒有包含這台主機。Gmail 這類信箱收到這種信,會懷疑是冒名寄的。 - 連對外寄信的連線都被擋:有些雲端主機預設擋住對外的 25 埠。
還有一點要知道:wp_mail() 回傳「成功」,只代表信已經交給寄信程式,不代表對方真的收到了。
1. 後台加一個「寄測試信」頁面
// 後台「工具 → 寄測試信」:輸入信箱按一下,馬上知道網站寄不寄得出信,寄不出去會顯示原因
add_action( 'admin_menu', function () {
add_management_page( '寄測試信', '寄測試信', 'manage_options', 'zw-test-mail', 'zw_test_mail_page' );
} );
function zw_test_mail_page() {
$result = '';
if ( isset( $_POST['zw_to'] ) && check_admin_referer( 'zw_test_mail' ) ) {
$to = sanitize_email( wp_unslash( $_POST['zw_to'] ) );
$error = '';
$catch = function ( $e ) use ( &$error ) {
$error = $e->get_error_message();
};
add_action( 'wp_mail_failed', $catch );
$ok = wp_mail( $to, '【' . get_bloginfo( 'name' ) . '】測試信', "收到這封信,代表網站可以正常寄信。\n寄出時間:" . wp_date( 'Y-m-d H:i:s' ) );
remove_action( 'wp_mail_failed', $catch );
$result = $ok
? '<div class="notice notice-success"><p>已經交給寄信程式寄出,請到 ' . esc_html( $to ) . ' 收信(也看一下垃圾信件匣)。</p></div>'
: '<div class="notice notice-error"><p>寄不出去:' . esc_html( $error ? $error : '沒有錯誤訊息' ) . '</p></div>';
}
?>
<div class="wrap">
<h1>寄測試信</h1>
<?php echo $result; // 上面已經跳脫過 ?>
<form method="post">
<?php wp_nonce_field( 'zw_test_mail' ); ?>
<p><input type="email" name="zw_to" class="regular-text" required value="<?php echo esc_attr( wp_get_current_user()->user_email ); ?>"></p>
<?php submit_button( '寄一封測試信' ); ?>
</form>
</div>
<?php
}加上之後,後台「工具」底下會多一個「寄測試信」:
- 預設填的是自己登入帳號的 Email,可以改成別的信箱,例如老闆的手機常用信箱。
- 寄不出去:紅色框直接顯示原因,例如「寄不出去:無法具現化 mail 函式。」
- 交給寄信程式成功:綠色框提醒去收信,也要看垃圾信件匣。成功交出但收不到,問題就在後面的「垃圾信、退信」那一段。
- 只有管理員(
manage_options權限)看得到這個頁面,送出時會檢查 nonce,別人沒辦法用外部表單叫你的網站亂寄信。
建議收 Gmail、Outlook、公司信箱各寄一封,看看是不是每一家都收得到。
2. 寄信失敗時記下原因
// 寄信失敗時記下原因:寫進 PHP 錯誤紀錄(主機的 error_log,或開了 WP_DEBUG_LOG 時的 wp-content/debug.log)
add_action( 'wp_mail_failed', function ( $error ) {
$data = (array) $error->get_error_data();
$to = isset( $data['to'] ) ? implode( ', ', (array) $data['to'] ) : '';
error_log( sprintf(
'[寄信失敗] %s|收件人:%s|主旨:%s',
$error->get_error_message(),
$to,
isset( $data['subject'] ) ? $data['subject'] : ''
) );
} );wp_mail_failed是寄信失敗時 WordPress 會觸發的動作,錯誤物件裡有錯誤訊息,以及收件人、主旨、內容。- 這裡把「錯誤訊息、收件人、主旨」寫成一行,存進 PHP 的錯誤紀錄。有開
WP_DEBUG_LOG的網站會寫進wp-content/debug.log;沒開的話,寫進主機的 PHP 錯誤紀錄(位置問主機商,或在主機控制台找 error log)。 - 信的內容沒有記,避免把客人填的資料寫進紀錄檔。
debug.log 怎麼開、看完要記得關,可以看〈WordPress 出現 500 錯誤怎麼辦〉裡的說明。
3. 改用 SMTP 寄信
SMTP 就是用一個真的信箱帳號登入寄信,像用 Outlook 寄公司信一樣。對方收到的信,寄件人是真的存在、網域也對得上的信箱,比較不會被當成垃圾信。
// 改用 SMTP 寄信:帳號、密碼寫在 wp-config.php,這裡只讀常數
add_action( 'phpmailer_init', function ( $phpmailer ) {
if ( ! defined( 'ZW_SMTP_HOST' ) ) {
return; // 沒設定就照 WordPress 原本的方式寄
}
$phpmailer->isSMTP();
$phpmailer->Host = ZW_SMTP_HOST;
$phpmailer->Port = (int) ZW_SMTP_PORT;
$phpmailer->SMTPAuth = true;
$phpmailer->Username = ZW_SMTP_USER;
$phpmailer->Password = ZW_SMTP_PASS;
$phpmailer->SMTPSecure = 465 === (int) ZW_SMTP_PORT ? 'ssl' : 'tls';
// 寄件人改成 SMTP 帳號本身,避免被收件端當成冒名
$phpmailer->setFrom( ZW_SMTP_USER, get_bloginfo( 'name' ), false );
} );帳號、密碼不要寫在 functions.php。這段程式碼只讀常數,常數寫在網站根目錄的 wp-config.php,放在 require_once ABSPATH . 'wp-settings.php'; 這一行的上面:
// SMTP 寄信設定
define( 'ZW_SMTP_HOST', 'smtp.gmail.com' );
define( 'ZW_SMTP_PORT', 587 );
define( 'ZW_SMTP_USER', 'shop@example.com' );
define( 'ZW_SMTP_PASS', '應用程式密碼' );wp-config.php沒加常數,程式碼就不會改任何東西,照 WordPress 原本的方式寄。可以先放程式碼,確定帳號後再加常數。- 埠號:587 用 TLS、465 用 SSL,程式碼會依埠號自動選。兩個都可以就用 587。
- 寄件人改成 SMTP 帳號本身,名稱用網站名稱。很多 SMTP 服務只允許用登入的帳號當寄件人,寫別的信箱會被拒絕或改掉。
用 Gmail 寄:主機填 smtp.gmail.com。密碼不是 Gmail 的登入密碼,要先開啟兩步驟驗證,再建立一組「應用程式密碼」,填那 16 個字元。細節可以看〈用 Gmail 收發公司企業信箱〉的寄件(SMTP)設定。
用公司信箱(主機商、網域商提供的)寄:SMTP 主機名稱、埠號,問提供信箱的廠商,或看他們的設定說明。
已經裝了 SMTP 外掛(例如 WP Mail SMTP)的網站,就不要再加這一段,兩邊會改同一組設定。寄測試信頁面和記錄錯誤的程式碼,和外掛一起用沒有問題。
常見的錯誤訊息代表什麼
以下是 WordPress 繁體中文介面會顯示的訊息(括號裡是英文原文):
- 「無法具現化 mail 函式。」(Could not instantiate mail function.) 主機沒有可以用的寄信程式。最直接的解法:改用上面的 SMTP 寄信。
- 「SMTP 錯誤: 無法連線至 SMTP 主機。」(Could not connect to SMTP host.) 連不到 SMTP 主機。檢查主機名稱、埠號有沒有打錯;587 不行換 465 試試;還是不行,問主機商有沒有擋對外的連線。
- 「SMTP 錯誤: 無法驗證。」(Could not authenticate.) 連上了,但帳號或密碼錯。用 Gmail 的話,確認填的是應用程式密碼。
- 「無效的電子郵件地址」(Invalid address) 收件人或寄件人的 Email 格式不對。常見是表單外掛的收件人欄位多打了空白、全形符號,或用分號隔開好幾個信箱。
- 顯示成功,卻收不到 先看垃圾信件匣。接著檢查寄件網域的 SPF、DKIM 設定(寄信服務商、主機商的說明裡都有該填什麼)。網域的 Email 設定可以用〈網站自我檢查的免費工具〉裡的 Email 檢查工具看。
實際測試的結果
測試站:WordPress 7.1.3(繁體中文)、PHP 8.3,主機本身沒有寄信程式,模擬最常見的寄不出信情況。
沒有加任何程式碼
- WordPress 用主機的
mail()寄,寄件人是wordpress@(網站網域)、名稱是「WordPress」。 - 寄信失敗,錯誤訊息是「無法具現化 mail 函式。」,但網站上什麼都看不到,沒有任何提示。
加上寄測試信頁面
- 後台「工具」底下出現「寄測試信」,預設填好管理員的 Email。
- 按下寄出,紅色框顯示「寄不出去:無法具現化 mail 函式。」
- 換成信件可以順利交出的情況,綠色框顯示「已經交給寄信程式寄出,請到…收信(也看一下垃圾信件匣)。」信的主旨是「【網站名稱】測試信」,內容有寄出時間。
加上記錄錯誤
debug.log 多了這樣一行(時間是 UTC):
[16-Oct-2026 06:15:48 UTC] [寄信失敗] 無法具現化 mail 函式。|收件人:test@example.com|主旨:測試主旨再加上 wp-config.php 的 SMTP 常數(用假的 Gmail 帳號測試)
- 寄信方式從
mail變成smtp,主機smtp.gmail.com、埠號 587、加密方式 TLS、有登入驗證。 - 寄件人變成 SMTP 帳號
shop@example.com,名稱變成網站名稱。 - 測試站的環境沒辦法和 Gmail 完成加密連線(SSL 憑證驗證失敗),寄信失敗;錯誤訊息「SMTP 錯誤: 無法連線至 SMTP 主機。」加上連線失敗的細節,一樣被記進
debug.log。
拿掉 wp-config.php 的常數,又回到原本的 mail() 寄信,程式碼不會出錯。
延伸閱讀
- WordPress 出現 500 錯誤怎麼辦?「這個網站發生嚴重錯誤」的排查順序
- 用 Gmail 收發公司企業信箱:寄件(SMTP)設定與 Gmail 停用 POP 後的收信方式
- WordPress 留言審核通過自動寄信通知留言者(含回覆通知程式碼)
網站的信寄不出去,損失的常常是看不見的詢價。正威網路行銷是 25 年經驗的基隆網頁設計工作室,網站管家年費包含系統、外掛與安全性更新,以及每半年一次網站健檢報告,台北與全台客戶也歡迎來聊聊。







發表留言
還沒有人留言,歡迎第一個分享你的想法或問題。留言經審核後才會顯示,Email 不會公開。