我的表格viewer
包含id
,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吗?
答案 0 :(得分: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()
作为旁注,如果变量的值( s )来自外部,则查询易受SQL Injection
攻击。请查看下面的文章,了解如何防止它。通过使用PreparedStatements
,您可以摆脱在值周围使用单引号。
答案 1 :(得分:2)
假设您的mysql_query
正确执行,它将不会返回false。你应该做的是检查它返回的行数。您可以使用mysql_num_rows
。
另外,请注意mysql_*
手册页顶部的大红色警告框。
答案 2 :(得分: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() );
}
答案 3 :(得分:1)
$search_ip
永远不会== false
,因为它是对结果的引用。请改用mysql_num_rows($earch_ip)
。另请注意,mysqli
替换了此代码,您的代码实际上已弃用
答案 4 :(得分: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) {
....
}