我在这里阅读了一些答案并获得“精心锁定”。我是新人,不在这方面工作,只是在过去的43年里自学了。我转换了我前几天写的点击计数器中的一段代码,它只是计算IP运行被拒绝的访问页面的次数。代码检查IP是否已存在于数据库表中(唯一)。如果是,它只是递增和更新。如果不存在,则将其值为1插入。
一切都很好,然后我发现测试时没有增加。所以我将其隔离并发现它不会识别表列值来更新它,并且当它尝试将其作为新值插入时抛出异常,因为它是唯一的。
我看了看,似乎无法理解为什么它在我的hitcounter中工作得很好,但在这里惨遭失败?!?
$IP = $_SERVER['REMOTE_ADDR'];
$IP = preg_replace('#[^0-9\.]#','',$IP);
$db_table = 'deniedcounter';
echo 'Enter denied_record.php<br />';
//$IP = str_replace('.','x',$IP);
function setdeniedcounter($IP, $db_handle, $db_table){
$hits = null;
$ip = "'".$IP."'";
try{
echo "SELECT * FROM $db_table WHERE ip = $ip".'<br />';
$stmt = $db_handle->query("SELECT * FROM $db_table WHERE ip = $ip");
$row_count = $stmt->rowCount();
echo $row_count.' = Rows selected.<br />';
}
catch(PDOException $e){
db_exception_handler($e);
}
if($row_count == 1){
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo $row['ip'].' '.$row['hits'].'<br />';
$hits = $row['hits']; $ip = $row['ip'];
$hits++;
try{
$stmt = $db_handle->prepare("UPDATE $db_table SET hits=? WHERE ip=?");
$stmt->execute(array($hits, $ip));
$affected_rows = $stmt->rowCount();
echo $affected_rows.'<br />';
}
catch(PDOException $e){
db_exception_handler($e);
}
exit();
}
elseif($row_count == 0){
$hits = 1;
try{
$stmt = $db_handle->prepare($sql = "INSERT INTO $db_table(ip, hits) VALUES(?, ?)");
$stmt->execute(array($ip, $hits));
$affected_rows = $stmt->rowCount();
//echo $affected_rows.'<br />';
}
catch(PDOException $e){
db_exception_handler($e);
}
}
//echo 'Hits = '.$hits.'<br />';
if(isset($hits)){return $hits;}
}
$db_handle = db_OPEN($db_host, $db_name, $db_username, $db_pwd);
if(strlen($IP) > 6){$da_hits = setdeniedcounter($IP, $db_handle, $db_table);}
if(!isset($da_hits)){$da_hits = setdeniedcounter('ALERT', $db_handle, $db_table);}
$db_handle = db_CLOSE($db_handle);
echo 'Exit denied_record.php<br />';
exit();
====================
输出:
Enter denied_record.php
SELECT * FROM deniedcounter WHERE ip = '127.0.0.1'
0 = Rows selected.
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry ''127.0.0.1''
for key 'ip'
Exit denied_record.php
答案 0 :(得分:2)
Mysql有一个特殊的操作符。
首先不需要SELECT - 只需要使用一些额外的代码INSERT:
INSERT INTO $ db_table(ip,hits)VALUES(?,?)ON DUPLICATE KEY UPDATE hits = hits + 1
所以,你的功能实际上必须是
function setdeniedcounter($ip, $db_handle, $db_table) {
$sql = "INSERT INTO $db_table(ip, hits) VALUES(?, 1)
ON DUPLICATE KEY UPDATE hits=hits+1";
$stmt = $db_handle->prepare();
$stmt->execute(array($ip));
}
如果你想要返回命中,你需要选择它们
答案 1 :(得分:1)
问题是你正在检查两个不同的东西。当您使用准备好的语句问号时,MySQL会插入自己的单引号。所以你最初检查的是127.0.0.1是否存在,而不是。然后你尝试插入'127.0.0.1'(包括值中的单引号),这已经存在,这就是它失败的原因。
答案 2 :(得分:-3)
数据库中的IP字段是一个字符串。可能在第一个sql语句中你必须使用引号?
$db_handle->query("SELECT * FROM $db_table WHERE ip = $ip");
替换为:
$db_handle->query("SELECT * FROM $db_table WHERE ip = '".$ip."'");