0

我有一个viewerid, ip, date_last_viewed&blog_id作为列的表。我首先检查是否存在具有相同 IP 和 blog_id 的特定条目。如果是,它会更新日期。否则,它会插入一个新条目。

我的代码如下:

$search_ip = mysql_query("SELECT ip FROM viewer WHERE ip = '".$_SERVER['REMOTE_ADDR']."' AND blog_id= '".$b_id."' ");

if ($search_ip == false){
    $insert_ip = mysql_query("INSERT INTO viewer (ip, blog_id, date_last_viewed) VALUES ('".$_SERVER['REMOTE_ADDR']."', '".$b_id."', NOW())");
}
else {
    $update_ip = mysql_query("UPDATE viewer SET date_last_viewed = NOW() WHERE ip = '".$_SERVER['REMOTE_ADDR']."' AND blog_id='".$b_id."' ");           
}

该表未插入任何内容。我在这里做错了什么?另外,由于我是 PHP 编程的新手,有人可以告诉我如何将上述代码修改为 PDO 吗?

4

5 回答 5

5

实际上,您只需一个查询即可完成。

MySQL 有一个特殊的特性INSERT ... ON DUPLICATE KEY UPDATE,如果记录不存在则插入,如果记录已经存在则更新。您需要做的一件事是定义一个唯一的列(/s)

根据您的陈述,您需要在两列上定义唯一约束,

ALTER TABLE viewer ADD CONSTRAINT vw_uq UNIQUE (ip, blog_id)

并执行此语句,

INSERT INTO viewer (ip, blog_id, date_last_viewed)
VALUES ($_SERVER['REMOTE_ADDR'], b_id, NOW())
ON DUPLICATE KEY UPDATE date_last_viewed = NOW()

作为旁注,SQL Injection如果变量的值(s)来自外部,则查询很容易受到攻击。请看下面的文章,了解如何预防。通过使用PreparedStatements,您可以摆脱在值周围使用单引号。

于 2013-05-29T13:42:06.290 回答
2

假设您mysql_query正确执行,它不会返回错误。你应该做的是检查它返回的行数。您可以使用mysql_num_rows.

mysql_*另外,请注意手册页顶部的大红色警告框。

于 2013-05-29T13:41:52.473 回答
1

您应该首先添加错误处理程序。然后转到mysqli_并使用准备好的语句。

$search_ip = mysql_query( "SELECT ... " ) or die( mysql_error() );

if( mysql_num_rows($search_ip) == 0 ) {
     $insert_ip = mysql_query( "INSERT ... " ) or die( mysql_error() );
}
else {
     $update_ip = mysql_query( "UPDATE ... " ) or die( mysql_error() );
}
于 2013-05-29T13:41:47.643 回答
1

$search_ipwill never == false,因为它是对结果的引用。改为使用mysql_num_rows($earch_ip)。另请注意,mysqli替换它并且您的代码实际上已被弃用

于 2013-05-29T13:44:11.500 回答
0

这不是检查查询是否返回值的正确方法:

$search_ip = mysql_query("SELECT ip FROM viewer WHERE ip = '".$_SERVER['REMOTE_ADDR']."' AND blog_id= '".$b_id."' ");

if (mysql_num_rows($search_ip)==0) {
....
}
于 2013-05-29T13:43:07.260 回答