Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/255.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php WHERE不识别并插入抛出唯一异常_Php_Mysql_Sql_Pdo - Fatal编程技术网

Php WHERE不识别并插入抛出唯一异常

Php WHERE不识别并插入抛出唯一异常,php,mysql,sql,pdo,Php,Mysql,Sql,Pdo,我在这里读到了一些答案,我的思绪被锁住了。我是新来的,不在这里工作,只是在过去的43年里自学。我从前几天编写的命中计数器中转换了一段代码,它只计算IP运行我的拒绝访问页面的次数。代码检查IP是否已在数据库表中唯一。如果是,它只是增加和更新。如果它不在那里,它将以1的值插入它 一切都很好,然后我在测试时没有注意到增量。所以我隔离了它,发现它无法识别表列值来更新它,并且它在尝试将其作为新值插入时抛出异常,因为它是唯一的 我看了又看,似乎无法理解为什么它在我的击球员计数器中工作得很好,但在这里却失败得

我在这里读到了一些答案,我的思绪被锁住了。我是新来的,不在这里工作,只是在过去的43年里自学。我从前几天编写的命中计数器中转换了一段代码,它只计算IP运行我的拒绝访问页面的次数。代码检查IP是否已在数据库表中唯一。如果是,它只是增加和更新。如果它不在那里,它将以1的值插入它

一切都很好,然后我在测试时没有注意到增量。所以我隔离了它,发现它无法识别表列值来更新它,并且它在尝试将其作为新值插入时抛出异常,因为它是唯一的

我看了又看,似乎无法理解为什么它在我的击球员计数器中工作得很好,但在这里却失败得很惨

$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();

数据库中的IP字段是一个字符串。可能在第一条sql语句中必须使用引号

$db_handle->query("SELECT * FROM $db_table WHERE ip = $ip");
替换为:

$db_handle->query("SELECT * FROM $db_table WHERE ip = '".$ip."'");

Mysql为您提供了一个特殊的操作符。 无需先选择-只需插入一些额外代码:

插入$db_tableip,点击值?重复按键更新点击次数=点击次数+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));
}    

bu如果您希望返回点击数-您需要选择它们,但问题是您正在检查两种不同的内容。当您使用prepared语句问号时,MySQL会插入自己的单引号。因此,您最初检查的是127.0.0.1是否存在,而实际上没有。然后尝试在值中插入“127.0.0.1”,包括单引号,该值已经存在,这就是它失败的原因

您还应该为SELECT使用准备好的语句。还有,在过去的43年里,我自学了@Svish所说的。问题可能是因为您试图在prepared statements部分中插入'ip'而不是ip'。看第二个例子,也许这会有帮助。And:PDOStatement::rowCount返回受相应PDOStatement对象执行的最后一个DELETE、INSERT或UPDATE语句影响的行数。除了单引号外,对rowCount的误解也会影响结果。谢谢从那件事中学到了一些东西。我43年前开始编程。我终于开始玩服务器端和浏览器脚本语言了。我的网站现在已经有20多年的历史了,直到几周前,这些页面都是用HTML编写的,大约是很久以前的事了。。。呵呵。我在修改它时玩得很开心。从来没有意识到脚本已经走了多远,有一个内置的人机界面作为主干是多么美好。我的人机界面总是有问题。是的,很抱歉:$db_handle->querySELECT*FROM$db_table,其中ip='.$ip';看看他的嵌入式代码,注意他身体功能的第二行:但我认为这个问题和我试图解决的问题是一样的。由@juacala解释感谢大家的时间,并帮助像我这样的noob。要解决您的问题,请从$ip的变量定义中去掉单引号,然后执行以下操作之一:1使用准备好的语句进行第一个查询,其中ip=?或2写入,其中ip='$ip'变量中包含的单引号是导致问题的原因。谢谢。很高兴能帮上忙。如果回答了这个问题,请将其标记为正确答案。这对他没有帮助,因为他已经在$ip变量中添加了单引号。他没有为准备好的语句检查/使用正确的值。我终于让它在没有查询的情况下正确地准备和绑定,并且行计数是一个不正确的使用,正如其他海报的on所描述的那样。现在我将尝试上面的代码。那会让一切变得更容易。很高兴有你的常识!工作得很有魅力。。。太优雅了。非常感谢。我确实使用了名称空间,没有使用单引号,而且准备和绑定都很好。@Your Common-Sense-上校,我到处寻找一个地方来发送一封私人感谢信。找不到。非常感谢。仅仅了解条件SQL语句就让生活变得更轻松了。我不是严格的上校。只是一个笔名。很高兴你喜欢它。我一直追求的不仅仅是修复代码,还要使其简洁易读。所以,我的每一项工作都是针对它的。我喜欢帮助别人。所以,谢谢你对我谦虚努力的重视
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));
}