簡體   English   中英

防止網站范圍內的雙重提交

[英]Preventing a site-wide double submit

我很難找到這個問題的好標題,所以我希望這很清楚。 我目前在一個網站上使用TwitterOauth模塊發布推文。 在此過程中,我需要對提交的推文數量設置一個限制; 每小時只有一個

注意:我沒有使用數據庫的選項。 這對這個問題至關重要。

我已將以下內容合並到處理實際發布到Twitter API的PHP文件中:

# Save the timestamp, make sure lastSentTweet exists and is writeable
function saveTimestamp(){
    $myFile = "./lastSentTweet.inc";
    $fh = fopen($myFile, 'w');
    $stringData = '<?php function getLastTweetTimestamp() { return '.time().';}';
    fwrite($fh, $stringData);
    fclose($fh);
}

# Include the lastSentTweet time
include('./lastSentTweet.inc');

# Define the delay
define('TWEET_DELAY', 3600);

# Check for the last tweet
if (time() > getLastTweetTimestamp() + TWEET_DELAY) {
    // Posting to Twitter API here
} else {
    die("No.");
}

lastSentTweet.inc文件(chmod 777)的(初始)內容:

<?php function getLastTweetTimestamp() { return 1344362207;}

問題是,盡管這可行; 它允許意外的兩次提交; 如果有多個用戶(此腳本運行的站點當前非常繁忙)觸發了此腳本,則可能有2個提交到Twitter的提交(或更多,盡管尚未發生),而不僅僅是1個。是打開,寫入和關閉文件的(盡管是一分鍾)延遲,但我可能是錯的。

有誰知道導致意外兩次提交的原因(以及解決方法)?

您正在獲得比賽條件。 你將需要實現鎖定在你的文件,而你正在做的改變,但你需要附上兩個讀取(在include語句)和鎖內更新; 至關重要的是在您讀取文件的當前值然后使用新的時間戳對其進行更新時,確保沒有其他人(例如,另一個HTTP請求)正在使用該文件。

這將是相當無效的。 您還可以在PHP安裝中使用其他選項,以下是一些選項:

  1. 即使沒有數據庫服務器, 也可以使用數據庫: SQLite
  2. 您可以將時間戳存儲在APC中,並在更新時使用apc_cas()來檢測上次存儲的時間戳是否仍然是最新的。

更新

您的鎖定工作流程必須是這樣的:

  1. 獲取您存儲的時間戳記上的鎖。 如果你正在使用文件,你需要有開放的讀取寫入文件,並呼吁flock()就可以了。 如果另一個進程已將文件鎖定,則flock()將掛起,並且僅在獲得該鎖定后才返回,此時其他試圖鎖定該文件的進程將掛起。
  2. 從已經鎖定的文件中讀取存儲的時間戳。
  3. 檢查從存儲的時間戳記以來是否經過了所需的時間。
    • 在通過后,發送推文並將當前時間戳保存到文件; 否則,您不會觸摸存儲的時間戳。
  4. 釋放鎖(僅關閉文件就足夠了)。

這樣可以確保在您閱讀並測試了時間戳之后,但在存儲新時間戳之前,沒有其他進程可以更新該時間戳。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM