【问题标题】:Draw a comparison between an integer in a specific row and a count在特定行中的整数和计数之间进行比较
【发布时间】:2012-09-15 02:15:39
【问题描述】:

这是这个问题的后续问题:Check for specific integer in a row WHERE user = $name

我希望用户能够在我的网站上一天准确地发表五次评论。在这五次之后,用户必须等待 24 小时。 为了实现这一点,我在我的 MYSQL 数据库中提出了一个计数器,就在用户旁边。 所以用户的名字在哪里,计数器就在哪里。当它达到 5 时,它应该停止计数并在 24 小时后复位。为了检查我使用时间戳的时间。我检查时间戳是否超过 24 小时。如果是这种情况,计数器会被重置(-5)并且用户可以再次评论。为了做到这一点,我使用了下面的代码,但是它永远不会在五点停止,我的猜测是我的比较在某种程度上是错误的:

$counter = mysql_query("SELECT FROM table VALUES CommentCounterReset WHERE Name = '$name'");

if(!isset($_SESSION['ts'])); {
    $_SESSION['ts'] = time();
}

if  ($counter >= 5) { 
    if (time() - $_SESSION['ts'] <= 60*60*24){
        echo "You already wrote five comments.";
    }
    else {
        $sql = "UPDATE table SET CommentCounterReset = CommentCounterReset-5 WHERE Name = '$name'";   
    }     
}  
else {
 $sql = "UPDATE table SET CommentCounterReset = CommentCounterReset+1 WHERE Name = '$name'";
    echo "Your comment has been added.";
}

【问题讨论】:

  • 您的代码实际上并未执行存储在$counter 中的 SQL 查询(这也不是有效的 SQL 查询)。

标签: php mysql database integer compare


【解决方案1】:

你应该让他每天添加 5 次 cmets,而不是 24 小时后:

$db = new PDO('mysql:host=localhost;dbname=test', 'root', '', array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));

$stmt = $db->prepare("SELECT `Name`, `timestamp`, `CommentCounterReset` FROM `table` WHERE `Name`=:name");
$stmt->execute(array(':name' => $_GET['name']));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$lastComment = $row['timestamp']; // timestamp from database and not from $_SESSION because $_SESSION get's destroyed.
$countComments = $row['CommentCounterReset']; // number of comments added

$row_count = $stmt->rowCount();
if(!$row_count){
    $stmt = $db->prepare("INSERT INTO `table` VALUES(0, :name, :timestamp, 1)");
    $stmt->execute(array(':name' => $_GET['name'], ':timestamp' => date('U')));
    echo "Your comment has been added.";
} else {
    if($countComments > 4 && date('d') == date('d', $lastComment)){ // if number of comments are greater than 4 and is same day
        echo "You already wrote five comments today.";
    } else {
        if(date('d') != date('d', $lastComment)){ // if there are different days, reset the counter to 1
            $stmt = $db->prepare("UPDATE `table` SET `CommentCounterReset` = 1, `timestamp`=:timestamp WHERE `Name`=:name");
            $stmt->execute(array(':name' => $_GET['name'], ':timestamp' => date('U')));
        } else { // if it's same day increase counter with 1
            $stmt = $db->prepare("UPDATE `table` SET `CommentCounterReset` = `CommentCounterReset`+1 WHERE `Name`=:name");
            $stmt->execute(array(':name' => $_GET['name']));
        }
        echo "Your comment has been added.";
    }
}

mysql_*,但我非常反对!

$link = mysql_connect('localhost', 'root', '');
mysql_select_db('test', $link);

$stmt = mysql_query("SELECT `Name`, `timestamp`, `CommentCounterReset` FROM `table` WHERE `Name`='".mysql_real_escape_string($_GET['name'])."'");
$num = mysql_num_rows($stmt);

if(!$num){
    $stmt = mysql_query("INSERT INTO `table` VALUES(0, '".mysql_real_escape_string($_GET['name'])."', '".date('U')."', 1)");
    echo "Your comment has been added.";
} else {
    $row = mysql_fetch_assoc($stmt);
    $lastComment = $row['timestamp']; // timestamp from database and not from $_SESSION because $_SESSION get's destroyed.
    $countComments = $row['CommentCounterReset']; // number of comments added

    if($countComments > 4 && date('d') == date('d', $lastComment)){ // if number of comments are greater than 4 and is same day
        echo "You already wrote five comments today.";
    } else {
        if(date('d') != date('d', $lastComment)){ // if there are different days, reset the counter to 1
            $stmt = mysql_query("UPDATE `table` SET `CommentCounterReset` = 1, `timestamp`='".date('U')."' WHERE `Name`='".mysql_real_escape_string($_GET['name'])."'");
        } else { // if it's same day increase counter with 1
            $stmt = mysql_query("UPDATE `table` SET `CommentCounterReset` = `CommentCounterReset`+1 WHERE `Name`='".mysql_real_escape_string($_GET['name'])."'");
        }
        echo "Your comment has been added.";
    }
}

我的table

CREATE TABLE `table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `Name` varchar(30) NOT NULL,
  `timestamp` int(11) NOT NULL,
  `CommentCounterReset` int(11) NOT NULL,
  UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

【讨论】:

  • 嘿,首先非常非常感谢您提供此代码。 :) 非常感谢。但是我还没有使用 PDO,所以也许我做错了什么。为了调用它,我只是像往常一样做,对吧? (例如 www.myserver.com/Myphp.PHP?name=myName)?现在,我收到回显“您的评论已添加”,但计数器保持在 0。您可能知道为什么会这样吗?
  • 我建议您开始使用 PDO,因为www.myserver.com/Myphp.PHP?name=myName 很容易受到 SQL 注入的攻击。但是我没有测试这段代码,但它应该可以工作。您的查询将是Name='".mysql_real_escape_string($_GET['name'])."',而不是每个 SQL 的最后一部分。
  • 还要确保你的表中有时间戳行作为 INT
  • 谢谢,我让它工作了,但是它总是给我回声“你的评论已被添加”,总是将它重置为零。我不知道为什么。此外,当尝试将 TIMESTAMP 放入而不是 CURRENT_TIMESTAMP 时,它会告诉我它不是默认值。
  • 我不知道你的时间戳是如何存储到数据库中的。我告诉过你让它成为 INT。
【解决方案2】:

你写:

$counter = mysql_query("SELECT FROM table VALUES CommentCounterReset WHERE Name = '$name'");

if  ($counter >= 5) {

...但是$counter 是一个资源,而不是查询的结果。所以比较是有缺陷的。

您应该运行查询然后获取值:

$exec = mysql_query("SELECT CommentCounterReset FROM table WHERE Name='$name';");
// Insert considerations about SQL injection and benefits of PDO here :-)
$tuple = mysql_fetch_assoc($exec);         // Might also do with fetch_array
$counter = $tuple['CommentCounterReset'];  // and $tuple[0]

不过,确保不超过限制的更好方法可能是将大部分工作留给 SQL。您存储帖子的名称和日期;表中的总行数最多为 5*number_of_users 。这样您就可以在同一天(而不是 24 小时)检查帖子。

// Clean the table. This will be done frequently, and it will be very fast
mysql_query("DELETE FROM comment_counters WHERE day < date(now());");
// It is also possible to add "... AND name='$name'" to the WHERE to reduce
// the number of affected rows; in this case the first version of the query
// ought to be run as a maintenance as near midnight as possible.

$exec = mysql_query("SELECT COUNT(*) < 5 AS ok FROM comment_counters WHERE name='$name';");
$data = mysql_fetch_assoc($exec);
mysql_free_result($exec);
$okay = $data['ok'];
if ($okay)
{
   // Okay to post
   mysql_query("INSERT INTO comment_counters (day, name) VALUES (date(now()), '$name');");
   // Do the rest of the posting
}
else
{
   // Cannot post.
}

【讨论】:

    猜你喜欢
    • 2012-10-14
    • 2017-07-06
    • 2023-03-13
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 2021-08-21
    • 2018-04-22
    • 1970-01-01
    相关资源
    最近更新 更多