繁体   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