gpt4 book ai didi

php - 令人费解的 php/Mysql 时间算术行为

转载 作者:行者123 更新时间:2023-11-29 01:32:13 25 4
gpt4 key购买 nike

我正在尝试选择在最后九十秒内输入的所有条目以及因此获取的每一行:

  • 显示他们的插入时间和当前时间之间的差异(作为 diff)
  • 显示记录将早于 90 秒的帖子剩余秒数(待定)

表结构:

attempt_id    |   username   |   attempt_ip   |   attempt_time  

这是我正在使用的查询:

SELECT *, (NOW() - attempt_time) diff, ( 90 + attempt_time - NOW() ) pending, 
NOW() nw FROM failed_login WHERE (username = 'some_username'
OR attempt_ip = '127.0.0.1') AND NOW() - attempt_time < 90;

但我得到的结果不一致:

测试运行 A Test Run

另一个测试运行
enter image description here

完整代码(如果您想尝试):

<?php

date_default_timezone_set('UTC');

function please_monsieur_db($qry)
{
$con = mysql_connect("localhost", "root", "");
if(!$con)
die("Unable to connect. " . mysql_error());

$db = mysql_select_db("temp_test");
if(!$db)
die("Unable to select database. " . mysql_error());

$res = mysql_query($qry);
if(!$res)
echo "\nQuery failed: $qry" . mysql_error();

return $res;
}

/* Insert 3 records with a time gap between 2 and 8 sec after each insert */
$k = 0;
while($k != 3)
{
$q = "INSERT INTO failed_login (username, attempt_ip) VALUES ('some_username', '127.0.0.1');";
$rs = please_monsieur_db($q);
if($rs)
echo "Insert @ " . time() . "\n";
sleep(rand(2, 8));
$k++;
}

/*
* SELECT all attempts in last ninety seconds and for each show the difference
* between their insertion time and the current time (diff) and
* number of seconds left post which the record will be older than 90 secs.
* Output the status every 2 seconds
*/
$m = 1;
while($m)
{
$query = "SELECT *, (NOW() - attempt_time) diff, (90 + attempt_time - NOW()) pending, NOW() nw FROM failed_login
WHERE (username = 'some_username' OR attempt_ip = '127.0.0.1') AND NOW() - attempt_time < 90;";

$res = please_monsieur_db($query);

if(!$res)
exit;

$ct = mysql_num_rows($res);
echo "\n";
while($row = mysql_fetch_array($res))
{
echo "Now:" . strtotime($row['nw']) . " || Attempt Time: " . strtotime($row['attempt_time']) .
" || Diff: [NOW() - attempt_time] = " . $row['diff'] . " || Pending [90-Diff] = : " . $row['pending'] . "\n";
}
echo "\n";
sleep(2);
$m = $ct;
}
?>

表格代码(如果需要):

CREATE DATABASE temp_test;
DROP TABLE IF EXISTS failed_login;

CREATE TABLE failed_login (
attempt_id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(256),
attempt_ip VARCHAR(16),
attempt_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

注意:对于实时输出,使用命令行运行。

$php -f /path_to_script/script.php  

最佳答案

这是因为您正在进行从 mysql 日期时间到整数的隐式转换。

例如mysql 认为时间(在我写这篇文章时)是 2011-12-15 13:42:10 但如果我要求 mysql 从中减去 90,它将锻炼 20111215134210 - 90 = 20111215134120 即 13:41:20 即 50几秒钟前。

要么将时间视为整数(通过与 unix 时间戳相互转换,如 liquorvicar 所建议的那样),要么使用日期函数对日期值进行数学运算:

SELECT *, 
timediff(NOW(), attempt_time) diff,
timediff(NOW(), attempt_time + INTERVAL 90 SECONDS) pending,
NOW() nw
FROM failed_login
WHERE (username = 'some_username'
OR attempt_ip = '127.0.0.1')
AND NOW() - INTERVAL 90 SECONDS > attempt_time;

(请注意,我还重写了最后一个过滤器表达式,以便表列在表达式的一侧被隔离——当列未被索引时,速度优势很小,但当它被索引时,速度优势很大) .

或者使用 seconds-since-epoch....

SELECT *, 
UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(attempt_time) diff,
UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(attempt_time) + 90 pending,
NOW() nw
FROM failed_login
WHERE (username = 'some_username'
OR attempt_ip = '127.0.0.1')
AND UNIX_TIMESTAMP(NOW()) - 90 > UNIX_TIMESTAMP(attempt_time);

(这显然不能使用索引优化)。

关于php - 令人费解的 php/Mysql 时间算术行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8516975/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com