2011-04-28 76 views
0

我一直在尋找一個解決方案的小時,或者我找不到合適的詞來描述我在搜索引擎中需要的東西,或者我只是找不到東西而已。防止訪問者每天發佈超過2帖子的方法(PHP MySQL)

這裏的情況: 我目前正在建立一個網站,我有一個部分,遊客可以發佈消息,有點像「留言」。但是,我想限制IP地址每天2個帖子。我原以爲這很容易,只需將IP地址,日期和時間以及所有其他數據插入到MySQL表中,然後比較每個IP的時間和日期。類似的東西......然後當我開始研究它時,想到了很多問題。如果IP在多天內發佈超過2條消息,我將如何比較條目?你甚至會如何準確地比較日期和時間?什麼是比較的最佳時間和日期格式?是否有更好的方法,比如可以比較的自我過期數據?等等。很抱歉,如果這看起來像這樣一個簡單的任務,但我很難找到答案。試圖搜索一切,如「MySQL的PHP​​時間限制」,「PHP的MySQL防止垃圾郵件定時器」,「PHP的MySQL的計時器像megavideo」等

只是爲了澄清,我需要一個很好的方法,防止訪問者張貼超過每天2封郵件。這是任何訪客可以發佈的「留言」類。沒有登錄。

預先感謝您!

+0

歡迎來到stackoverflow。 – Johan 2011-04-28 11:02:12

+0

每天有兩篇文章「24小時內兩篇文章」或「兩篇文章在同一天」 - 意味着您可以在服務器時間23:59發佈兩條消息,然後在00:01發佈兩條消息嗎?下面的答案主要反映24小時內的帖子。 – cairnz 2011-04-28 11:37:08

回答

1

是這樣的:

posts_in_last_24_hours = select count(*) from posts where ip=? and date>(NOW()-86400) -- 24 hours ago 
if that is 2: 
    fail 
else: 
    post message 
+0

謝謝你,我會盡力看看我能否得到這個工作! – Pseudosudo 2011-04-28 10:32:34

1

如果您在數據庫中對每一個崗位的IP記錄,你可以檢查它是否已公佈的2倍以上,在過去X天與查詢計數記錄在最後X天即IP,這樣的數字:

SELECT COUNT (IP) FROM posts_log WHERE IP = 'the_user_ip' AND post_date > (NOW() - (X * (60 * 60 * 24))) 
+0

感謝您的輸入! – Pseudosudo 2011-04-28 10:31:20

1

創建的表中調用exceptions與結構id, ip, date

,當用戶發佈內容,執行類似的查詢:

$ip = $_SERVER['REMOTE_ADDR']; 
$query = "insert into exceptions set ip = '{$ip}',date = 'NOW()'"; 

和前提醒用戶交的東西補充一點:

$ip = $_SERVER['REMOTE_ADDR']; 
$count = mysql_num_rows(mysql_query("select count(*) 
     from exceptions where ip = '{$ip}' 
     and date > DATE_SUB(NOW(), INTERVAL 24 HOUR)")); 

if($count> 2) { 
    echo 'You have exceeded posting limits, please try again in 24 hours'; 
    exit; 
} 
1

使用觸發器

實錄IP並將其存儲在留言簿表中。

然後創建一個觸發器,像這樣:

DELIMITER $$ 

CREATE TRIGGER bi_guestbook_each BEFORE INSERT ON guestbook FOR EACH ROW 
BEGIN 
    DECLARE posts_today INTEGER; 

    SELECT COUNT(new.ip) INTO posts_today FROM guestbook 
    WHERE ip = new.ip AND postdate = new.postdate; 
    IF posts_today > 1 THEN BEGIN 
    //Force error by selecting from non-existing table 
    //this will prevent the insert from happening. 
    SELECT no_more_than_2_post_per_day_allowed 
    FROM before_insert_guestbook_error; 
    END; END IF; 

END$$ 

DELIMITER ; 

現在,你可以做刀片在你的PHP代碼擔心漲停。
觸發器將自動執行檢查。

使用INSERT ..選擇

如果你不想使用觸發器,使用INSERT ... SELECT語句。

首先確保場ip在表定義定義爲NOT NULL沒有默認值。
這會在嘗試將空值插入到留言簿表中時導致以下插入失敗。

<?php 
    $name = mysql_real_escape_string($_GET['name']); 
    $post = ..... 
    $ip = .... 
$query = "INSERT INTO guestbook (id, name, post_text, ip, postdate) SELECT 
      NULL AS id 
      , '$name' AS name 
      , '$post' AS post_text 
      , IF(guestbook.count(*)>=2,null,ip) AS ip 
      , CURDATE() AS postdate 
      FROM guestbook WHERE ip = '$ip' AND postdate = CURDATE()"; 

當然你也可以把IF(count(*) >= 2,null,...)在被定義爲在表定義NOT NULL任何列的地方。

鏈接:
選擇...插入:http://dev.mysql.com/doc/refman/5.0/en/insert-select.html
觸發:http://dev.mysql.com/doc/refman/5.1/en/triggers.html

+0

在風格上,我認爲觸發器不是正確的方法 - 除非你是數據庫嚮導,觸發器可能很難理解和調試,並且我已經看到團隊在數天內與無法解釋的行爲發生衝突,因爲沒有人記得在桌子上設置了一個觸發器,並以一種預料之外的方式射擊... – 2011-04-28 10:22:17

+0

嘿,謝謝你的回覆。我在mysql和php方面還是比較新的,但我還沒有學過觸發器。我會研究你的代碼並試一試。非常感謝你! – Pseudosudo 2011-04-28 10:34:43

0

你已經有了足夠合理的看答案,所以我不會給添加任何東西 - 但我確實認爲你需要小心使用IP地址作爲訪問者的唯一標識符。這不是一種可靠的識別用戶的方式 - 例如,單個公司/大學/政府安裝中的大多數人似乎都來自同一個IP地址,因此該實施會將該架構中的每個人限制爲每天2個帖子。

避免垃圾郵件的最佳方式是包含CAPTCHA--這對用戶來說是背後的痛處,但它可靠地遮蔽了機器人;除非你的網站價值超高,否則垃圾郵件發送者的動機不足以讓人類發佈垃圾郵件。

+0

嘿謝謝你的回覆!我已經實現了一個簡單的驗證碼系統,我在php文件中保存了一系列問題和答案,然後在表單提交之後將它們與ajax進行比較。我的目標是限制一些閒聊的訪問者濫發垃圾郵件。感謝你的關心! – Pseudosudo 2011-04-28 10:27:54

1

你可以簡單地使用cookie來實現這一點。 無論如何,任何確定足以繞過發佈限制的人都能夠繞過IP阻止,因爲代理和動態IP使其變得非常簡單。所以,通過cookie或IP進行阻止對彼此有用(不是特別),但cookie更容易實現:

如果您在cookie中存儲計數器並將截止日期設置爲24小時未來。 然後,您可以在用戶發佈條目時遞增計數器,只需檢查計數器以查看它們是否已達到其限制。

這樣,您就不必擔心會發生數據庫問題,並可能引入任何性能問題。


建立在內維爾K的captcha點。如果垃圾郵件是您主要關心的問題,請嘗試使用negative captcha - 因爲他們從未看到它,所以不會影響用戶的體驗。

+0

-1一個人可以很容易地禁用或刪除cookies並繼續垃圾網站 – 2011-04-28 14:15:14

+0

是的,他們可以很容易地改變ip。因此有關它的序言。 – Alex 2011-04-28 15:20:45

+0

+1因爲沒有解決方案將是「完美」 – Pat 2011-05-31 06:53:02