
辦「留言抽獎」「留言分享心得」這類活動時,常會遇到同一個人連續留好幾則,想多拿幾次抽獎機會。這時就需要「每個人在同一篇文章只能留言一次」的規則。
WordPress 內建只會擋「內容完全一樣的重複留言」和「短時間內連續留言」,換幾個字就能再留,沒有「每人一則」的功能。下面用一段程式碼做到。
怎麼判斷是「同一個人」?
- 有登入的會員:用會員帳號判斷,最準確。
- 沒登入的訪客:用留言時填的電子郵件判斷。
- 為什麼不用 IP 判斷:同一間公司、學校,或同一家電信的手機網路,常常很多人共用同一個對外 IP,用 IP 判斷會誤擋不同的人;反過來,同一個人換個網路就又能留言。所以這裡不用 IP。
程式碼
加到子主題的 functions.php,或用 Code Snippets 外掛新增:
PHP
add_filter( 'preprocess_comment', function ( $commentdata ) {
// 只檢查一般留言(不含 Pingback、Trackback)
$type = isset( $commentdata['comment_type'] ) ? $commentdata['comment_type'] : '';
if ( ! in_array( $type, array( '', 'comment' ), true ) ) {
return $commentdata;
}
// 管理員、編輯不受限制
if ( current_user_can( 'moderate_comments' ) ) {
return $commentdata;
}
// 回覆別人的留言不受限制(想連回覆都限制,就把這段刪掉)
if ( ! empty( $commentdata['comment_parent'] ) ) {
return $commentdata;
}
$args = array(
'post_id' => (int) $commentdata['comment_post_ID'],
'parent' => 0,
'status' => 'all', // 已核准與待審核的都算
'count' => true,
);
$user_id = get_current_user_id();
if ( $user_id ) {
$args['user_id'] = $user_id;
} elseif ( ! empty( $commentdata['comment_author_email'] ) ) {
$args['author_email'] = $commentdata['comment_author_email'];
} else {
return $commentdata;
}
if ( get_comments( $args ) > 0 ) {
wp_die(
'這篇文章每個人只能留言一次喔!您的留言已經送出過了(可能還在等待審核)。',
'已經留言過了',
array( 'response' => 409, 'back_link' => true )
);
}
return $commentdata;
} );程式碼在做什麼?
preprocess_comment會在留言存進資料庫之前執行,發現已經留過言,就用wp_die()顯示提示訊息,留言不會被儲存。- 用
get_comments()查詢「這篇文章裡,這個帳號或這個電子郵件留過幾則」,WordPress 會用安全的方式組合查詢,不用自己寫 SQL。 'status' => 'all'代表「已核准」和「待審核」的留言都算,避免留言還在審核中,對方又重複送出。被你標成垃圾留言或丟進垃圾桶的不算。- 有審核留言權限的管理員、編輯不受限制,站長可以在同一篇文章回覆很多次。
- 回覆別人的留言預設不受限制,這樣留言者還能回應你的回覆。只想限制「第一層」的留言,保留這段就好。
- 錯誤訊息的狀態碼 409,跟 WordPress 內建擋重複留言時用的一樣;
back_link會在訊息下方顯示「返回」連結。
只想限制特定幾篇文章
通常只有活動文章需要這個規則。在程式碼一開頭($type 那一行的上面)加上這段,就只會套用在指定的文章:
PHP
// 只限制這幾篇文章(填文章 ID)
$limited_posts = array( 123, 456 );
if ( ! in_array( (int) $commentdata['comment_post_ID'], $limited_posts, true ) ) {
return $commentdata;
}文章 ID 在後台編輯文章時,網址列裡 post= 後面的數字就是。
舊版寫法為什麼不能用
這篇文章舊版的程式碼,是直接把留言者填的名稱、電子郵件接進 SQL 查詢指令裡。這會造成 SQL Injection(資料隱碼攻擊) 漏洞:有心人只要在「名稱」欄位輸入特殊的字元與指令,就有機會改變查詢的內容,讀取甚至破壞你的資料庫。
另外,舊寫法用「名稱相同」判斷同一個人,兩個不同的訪客都叫「小明」,第二個人就不能留言了;再加上 IP 判斷,同一間公司的同事也會互相擋到。如果你的網站還在用舊版程式碼,請盡快換成上面的寫法。
這個做法的限制
- 換一個電子郵件就能再留言:沒登入的訪客填什麼信箱,網站無法驗證。想要嚴格的一人一次,要搭配「設定 → 討論」裡「使用者必須註冊並登入才能發佈留言」的選項,只讓會員留言。
- 活動結算還是要人工檢查:抽獎前把留言匯出或看過一遍,確認有沒有明顯是同一個人用不同信箱重複參加。
- 垃圾留言還是要另外擋:這段只限制次數,不會判斷內容是不是廣告,防垃圾留言的做法請看延伸閱讀的第一篇。
延伸閱讀
- WordPress 防垃圾留言總整理:外掛、留言設定、蜜罐與字數限制
- WordPress 留言審核通過自動寄信通知留言者(含回覆通知程式碼)
- WordPress 悄悄話留言:讓訪客勾選「只給站長看」的私密留言
活動留言的規則事先想周到,後面的抽獎、統計才不會一團亂。正威網路行銷是 25 年經驗的基隆網頁設計工作室,提供客製化網頁設計,網站需要特別的留言或活動功能,歡迎來聊聊。







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