【问题标题】:prepared statement inside class is not working课堂内准备好的语句不起作用
【发布时间】:2019-01-09 08:09:29
【问题描述】:

我正在使用下面的代码从我的数据库中获取与用户输入的年份和月份相匹配的数据。

连接:

class ConnectDB{

    private $servername;
    private $username;
    private $password;
    private $dbname;


    protected function connect(){

        $this->servername ="localhost";
        $this->username ="root";
        $this->password ="";
        $this->dbname ="dbexpense";

        $conn = new mysqli($this->servername,$this->username,$this->password,$this->dbname);

            if($conn -> connect_error) {

                die("connection failed:".$conn-> connect_error);
            }

        return $conn;

        }
}

提取数据的类:

<?php

class SelectAMonthGet extends ConnectDB {

    var $year;
    var $month;


    function __construct( ){

        $this->year = $_POST['year'];
        $this->month = $_POST['analyze_options_month'];
    }

    protected function SelectAMonthGetData(){

    $year =  $this->year; 
    $month = $this->month;


    $sql = $this->connect()->prepare("SELECT * FROM wp_myexpenses WHERE YEAR(date) = ? AND MONTH(date) = ? order by date,id");

    $sql->bind_param("ss",$year,$month);

    $result = $sql ->execute();  

        $numRows = $result->num_rows;

            if($numRows > 0) {

                while ($row = $result->fetch_assoc()){

                $data[] = $row;
                }

                return $data;

            }
    }

}

?>

但即使数据库中有数据,它也没有显示任何结果。

当我使用没有准备好的语句的代码时,我能够得到一个结果,如下所示:

没有准备好的语句的代码(工作):

class SelectAMonthGet extends ConnectDB {

    var $year;
    var $month;


    function __construct( ){

        $this->year = $_POST['year'];
        $this->month = $_POST['analyze_options_month'];
    }

    protected function SelectAMonthGetData(){

    $year =  $this->year;; $month = $this->month;
    $sql = "SELECT * FROM wp_myexpenses WHERE YEAR(date) = '$year' AND MONTH(date) = '$month' order by date,id";

        $result = $this->connect()->query($sql);
        $numRows = $result->num_rows;

            if($numRows > 0) {

                while ($row = $result->fetch_assoc()){

                $data[] = $row;
                }

                return $data;

            }
    }

}

?>

我想使用准备好的语句来避免 SQL 注入。我无法理解我的代码有什么问题?有人可以在这里指导我吗?

更新: 正如 ADyson 在 cmets 中所建议的那样,启用了错误报告。它给出以下错误:

Notice: Trying to get property of non-object in **** on line 34

第 34 行:

$numRows = $result->num_rows;

更新:

将代码更改为包含 get_result(),如下所示

    protected function SelectAMonthGetData(){

    $year =  $this->year; 
    $month = $this->month; 

    $sql = $this->connect()->prepare("SELECT * FROM wp_myexpenses WHERE YEAR(date) = ? AND MONTH(date) = ? order by date,id");

    $sql->bind_param("ss",$year,$month);

    $sql ->execute();  

$result = $sql->get_result();


        $numRows = $result->num_rows;

            if($numRows > 0) {

                while ($row = $result->fetch_assoc()){

                $data[] = $row;
                }

                return $data;

            }
    }

但现在它给出错误:

Fatal error: Uncaught Error: Call to undefined method mysqli_stmt::get_result() in ****:28

在检查一些解决方案后,错误是由于未启用 mysqlnd 驱动程序。在我的情况下这是真的。 是否有任何替代解决方案来获得它?

【问题讨论】:

  • 在 Query 中使用 SELECT * 不是一个好习惯。
  • 是否检查了 $year 和 $month 的值?
  • @UmarAbdullah:是的。我检查了 $year 和 $month 的值。它按预期显示。 var_dump 数据:字符串(4)“2019”字符串(1)“1”
  • 试试 instedof ss ii
  • @HamzaNig:是的,我用 ii 试过,但没有运气

标签: php mysql prepared-statement


【解决方案1】:

这是两个解决方案,第一个是您的数据库调用类型mysqli,第二个是PDO

使用带有bind_result 不带get_result() 的mysqli 准备

  function SelectAMonthGetData(){
$year =  $this->year; 
$month = $this->month;
///*****************
$mysqli=$this->connect();
/* Crée une requête préparée */
$stmt = $mysqli->prepare("SELECT date,col2 FROM ets WHERE (YEAR(date) = ? AND MONTH(date) = ?) ");
    /* Lecture des marqueurs */
    $stmt->bind_param("ss", $year,$month);
      $stmt->execute();
     /* bind result variables */
    $stmt->bind_result($date, $col2); // here you can add your columns 

    /* fetch values */
    while ($stmt->fetch()) {
    $row=array();
    $row['date']=$date;
    $row['col2']=$col2;
    $data[] = $row;

    }
    return $data;


                                    }

使用mysqliget_result() 准备

     function SelectAMonthGetData(){
$year =  $this->year; 
    $month = $this->month;

 ///*****************

$mysqli=$this->connect();


/* Crée une requête préparée */
$stmt = $mysqli->prepare("SELECT * FROM ets WHERE YEAR(date) = ? AND MONTH(date) = ? ");

    /* Lecture des marqueurs */
    $stmt->bind_param("ss", $year,$month);

    /* Exécution de la requête */
    $result=$stmt->execute();
    /* instead of bind_result: */
    $result = $stmt->get_result();

    $numRows = $result->num_rows;

            if($numRows > 0) {

                while ($row = $result->fetch_assoc()){

                $data[] = $row;
                }

                print_r($data);
return $data;
            }




return null;







    }

PDO 并使用: 绑定参数:

$sql = "SELECT * FROM wp_myexpenses WHERE YEAR(date) = :year AND MONTH(date) = :month order by date,id"
    $stmt = $db_pdo->prepare($sql);
    $stmt->execute(Array(':year' => $year, ':month' => $month));
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);

【讨论】:

  • 从原始代码看来,OP 使用的是 mysqli,而不是 PDO
  • 谢谢你的权利,但我认为即使它仍然是一个答案可以帮助他对吗?
  • 如果他没有使用 PDO 连接到数据库,并且不想更改他的所有数据库代码以使用新库,则不会。而且mysqli不接受命名参数。
  • 这样好多了
  • @HamzaNig:它给出错误致命错误:未捕获错误:调用未定义的方法 mysqli_stmt::get_result()。未启用 mysqlnd 驱动程序。查看一些解决方案,我需要使用 bind_result & Fetch 选项
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-09
  • 2015-10-11
  • 2018-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多