Php Insert查询发出“无法获取mysqli_stmt”警告,但仍将数据发送到数据库

Php Insert查询发出“无法获取mysqli_stmt”警告,但仍将数据发送到数据库,php,mysqli,insert,prepared-statement,fetch,Php,Mysqli,Insert,Prepared Statement,Fetch,我有一张有两个下拉列表的表格。两者都使用数据库表中的值。 当访问者提交时,接下来的事情将发生: select查询将把选项id/POST值与数据库表中的值id进行比较。查询将在while循环中获取。while循环中有一个if-else,用于控制值是否相等。当它们运行时,则运行其他。 在else中,有一个insert查询,它将值id保存在一个新的数据库表中。 对于select和insert查询,我都使用准备好的语句。 获取select查询后,我在else$selControl->close中将其关闭

我有一张有两个下拉列表的表格。两者都使用数据库表中的值。 当访问者提交时,接下来的事情将发生:

select查询将把选项id/POST值与数据库表中的值id进行比较。查询将在while循环中获取。while循环中有一个if-else,用于控制值是否相等。当它们运行时,则运行其他。 在else中,有一个insert查询,它将值id保存在一个新的数据库表中。 对于select和insert查询,我都使用准备好的语句。 获取select查询后,我在else$selControl->close中将其关闭;然后开始第二次查询插入

当我运行带有submit的网站时,我得到一个错误:无法获取select查询的mysqli_stmt。但它仍然可以工作并插入到DB表中。 当我写$selControl->close时;包含/独占$insKeuze->close;从第三个else的insert after}或}after while,我得到一个错误,第一个查询必须在一个新的prepare语句之前关闭,这就是逻辑。 如果没有close语句,也会出现“准备前关闭”错误。 我更新了我的代码。 我添加了绑定参数。它将数据发送到数据库,但给出了错误

我需要做什么来停止错误

如果有人能帮助我,请提前感谢

代码:insert.php 此结构会产生相同的错误:

<?php
while ($selControl->fetch())
{
    echo "<script>alert('". $kLand . $kGerecht . $lLand_id . $gGerecht_id . "')</script>";
    // If selected land (land_id) is not the same as land_id in table landen
    // or selected gerecht (gerecht_id) is not the same as gerecht_id in table gerechten --> send echo.
    if ($kLand == $lLand_id && $kGerecht == $gGerecht_id)
    {
        $selControl->close();

        // If query is prepared --> bind the columns and execute the query.
        // Insert statement with placeholders for the values to database table landGerecht
        if ($insKeuze = $mysqli->prepare("INSERT INTO lab_stage_danush . landGerecht (land_id, gerecht_id) VALUES ( ?, ?)"))
        {
            // Bind land_id and gerecht_id as integers with $landKeuze and $gerechtKeuze.
            $insKeuze->bind_param('ii', $kLand, $kGerecht);

            // If statement is not executed then give an error message.
            if (!$insKeuze->execute())
            {
                echo "Failed to execute the query keuze: " . $mysqli->error;
            }
            $insKeuze->close();
        } else // Else give an error message.
            {
                echo "Something went wrong in the insert query connection: " . $mysqli->error;
            }

    } else // Else insert the selected values in table landGerecht.
        {
            // Message when the combination is not correct
            echo "<script>alert('Deze combinatie bestaat niet. Doe een nieuwe poging!');</script>";
        }
}
?>

正如您在评论中所说,您认为您的mysql连接之间存在冲突。我已经创建了一个类来解决这个问题

landen.php
 class landen{

    //define our connection variable, this is set in __construct
    private $mysqli;
    //this function is called when you create the class. $l = new landen($mysqlconn)
    public function __construct($mysqli){
        $this->mysqli = $mysqli;
    }

    //setter for kLand
    private $kLand = 0;
    public function setKland($k){
        $this->kLand = $k;
    }

    //setter for kGerecht
    private $kGerecht = 0;
    public function setKGerecht($k){
        $this->kGerecht = $k;
    }

    //run is our main function here.
    //if there was a return from select, it runs the insert.
    //will return true if select + insert BOTH pass.
    public function run(){
        if($this->select()){
            return $this->insert();
        }
        return false;
    }

    private function select(){
        $q = "SELECT landen.land_id, gerechten.gerecht_id FROM landen INNER JOIN gerechten ON landen.land_id = gerechten.land_id WHERE landen.land_id = ? AND gerechten.gerecht_id = ?";
        if($stmt = $this->mysqli->prepare($q)){
            $stmt->bind_param("ii",$this->kLand,$this->kGerecht);
            if($stmt->execute()){

                while ($stmt->fetch()){
                    /*
                    In your original code, you had a check to see if 
                    your post variable was the same as your returned query variables. 
                    This was not required as you are selecting from your database with those. 
                    They will **always** equal the post variables.

                    Line I'm disputing:  if ($kLand != $lLand_id || $kGerecht != $gGerecht_id) 
                    */  

                    return true;

                }
            }else{
                print_r("Error in select execute: {$this->mysqli->error}");
            }
        }else{
            print_r("Error in select prepare: {$this->mysqli->error}");
        }
        return false;
    }

    private function insert(){
        $q = "INSERT INTO lab_stage_danush . landGerecht (land_id, gerecht_id) VALUES ( ?, ?)";
        if($stmt = $this->mysqli->prepare($q)){
            $stmt->bind_param("ii",$this->kLand,$this->kGerecht);
            if($stmt->execute){
                return true;
            }else{
                print_r("Error in insert execute {$this->myqsli->error}");
            }
        }else{
            print_r("Error in insert prepare {$this->mysqli->error}");
        }

        return false;
    }

}
下面是一个关于如何运行的示例; insert.php

<?php
require_once("dbConfig.php");  

if(isset($_POST["submit"]) && !empty($_POST['landen']) && !empty($_POST['gerechten'])){
    //Call the class code when we need it
    require_once("landen.php");
    //create the class when we need it.
    $landen = new landen($mysqli);

    //set our variables
    $landen->setKland($_POST['landen']);
    $landen->setKGerecht($_POST['gerechten']);

    //landen run returns True if the select + insert statment passed.
    //It will return false if they fail.
    //if they fail, the page will not change and the errors will be outputted.
    //Or it's failing because nothing has been returned by the select function.

    if($landen->run()){
        //send out header to go to Keuze page,
        //you had a javascript location function here.
        header("Location: keuze.php");
        die();
    }else{
        //by default, let's say our queries are running fine and the only reason the select failed is because
        //the database couldn't find anything.
        echo "Nothing found with {$_POST['landen']} and {$_POST['gerechten']}. Please try again!";
    }

}

正如您在评论中所说,您认为您的mysql连接之间存在冲突。我已经创建了一个类来解决这个问题

landen.php
 class landen{

    //define our connection variable, this is set in __construct
    private $mysqli;
    //this function is called when you create the class. $l = new landen($mysqlconn)
    public function __construct($mysqli){
        $this->mysqli = $mysqli;
    }

    //setter for kLand
    private $kLand = 0;
    public function setKland($k){
        $this->kLand = $k;
    }

    //setter for kGerecht
    private $kGerecht = 0;
    public function setKGerecht($k){
        $this->kGerecht = $k;
    }

    //run is our main function here.
    //if there was a return from select, it runs the insert.
    //will return true if select + insert BOTH pass.
    public function run(){
        if($this->select()){
            return $this->insert();
        }
        return false;
    }

    private function select(){
        $q = "SELECT landen.land_id, gerechten.gerecht_id FROM landen INNER JOIN gerechten ON landen.land_id = gerechten.land_id WHERE landen.land_id = ? AND gerechten.gerecht_id = ?";
        if($stmt = $this->mysqli->prepare($q)){
            $stmt->bind_param("ii",$this->kLand,$this->kGerecht);
            if($stmt->execute()){

                while ($stmt->fetch()){
                    /*
                    In your original code, you had a check to see if 
                    your post variable was the same as your returned query variables. 
                    This was not required as you are selecting from your database with those. 
                    They will **always** equal the post variables.

                    Line I'm disputing:  if ($kLand != $lLand_id || $kGerecht != $gGerecht_id) 
                    */  

                    return true;

                }
            }else{
                print_r("Error in select execute: {$this->mysqli->error}");
            }
        }else{
            print_r("Error in select prepare: {$this->mysqli->error}");
        }
        return false;
    }

    private function insert(){
        $q = "INSERT INTO lab_stage_danush . landGerecht (land_id, gerecht_id) VALUES ( ?, ?)";
        if($stmt = $this->mysqli->prepare($q)){
            $stmt->bind_param("ii",$this->kLand,$this->kGerecht);
            if($stmt->execute){
                return true;
            }else{
                print_r("Error in insert execute {$this->myqsli->error}");
            }
        }else{
            print_r("Error in insert prepare {$this->mysqli->error}");
        }

        return false;
    }

}
下面是一个关于如何运行的示例; insert.php

<?php
require_once("dbConfig.php");  

if(isset($_POST["submit"]) && !empty($_POST['landen']) && !empty($_POST['gerechten'])){
    //Call the class code when we need it
    require_once("landen.php");
    //create the class when we need it.
    $landen = new landen($mysqli);

    //set our variables
    $landen->setKland($_POST['landen']);
    $landen->setKGerecht($_POST['gerechten']);

    //landen run returns True if the select + insert statment passed.
    //It will return false if they fail.
    //if they fail, the page will not change and the errors will be outputted.
    //Or it's failing because nothing has been returned by the select function.

    if($landen->run()){
        //send out header to go to Keuze page,
        //you had a javascript location function here.
        header("Location: keuze.php");
        die();
    }else{
        //by default, let's say our queries are running fine and the only reason the select failed is because
        //the database couldn't find anything.
        echo "Nothing found with {$_POST['landen']} and {$_POST['gerechten']}. Please try again!";
    }

}

只是我从球棒上看到的东西。。hack_filter但真正的hack_filter是bind_param,您在选择中使用prepare后没有使用它。请删除该过滤器,并选择结束您准备好的语句;我是否必须在执行之前添加bind_参数,以使用变量绑定landen.land_id和gerechten.gerecht_id?使用bind_param将变量放入查询中,这必须在->执行之前完成。在运行->execute后,您可以使用bind_result来获取结果。您很可能会收到该错误,因为->prepare在选择时失败。请找到$selControl=$mysqli->prepareSELECT的结束if语句括号。。。然后抛出}else{print\r$mysqli->error;}来定位实际问题;和$selControl->error。这是错误的。语句/查询没有返回错误,实际上是mysqli返回了错误。这里正确的语句应该是$mysqli->error@WillParky93所以,如果我没弄错的话,trim、stripslashes和htmlspecialchar对于获得安全的post值来说是不必要的?当有人更改源代码F12中的值时,我使用它们来过滤这些值,这是我从bat中看到的。。hack_filter但真正的hack_filter是bind_param,您在选择中使用prepare后没有使用它。请删除该过滤器,并选择结束您准备好的语句;我是否必须在执行之前添加bind_参数,以使用变量绑定landen.land_id和gerechten.gerecht_id?使用bind_param将变量放入查询中,这必须在->执行之前完成。在运行->execute后,您可以使用bind_result来获取结果。您很可能会收到该错误,因为->prepare在选择时失败。请找到$selControl=$mysqli->prepareSELECT的结束if语句括号。。。然后抛出}else{print\r$mysqli->error;}来定位实际问题;和$selControl->error。这是错误的。语句/查询没有返回错误,实际上是mysqli返回了错误。这里正确的语句应该是$mysqli->error@WillParky93所以,如果我没弄错的话,trim、stripslashes和htmlspecialchar对于获得安全的post值来说是不必要的?当有人更改源代码F12中的值时,我使用它们来过滤这些值