简体   繁体   中英

MySQLi Query Returning Single Result — Should Be Array of Results

Having some trouble with the following code. I've created a class to manage the DB connection, using what you see below as queryPreparedQuery and works fine when getting data for a single user, or any data that returns a single result using something like this...

include 'stuff/class_stuff.php';

function SweetStuff() {

    $foo = new db_connection();
    $foo->queryPreparedQuery("SELECT Bacon, Eggs, Coffee FROM Necessary_Items WHERE Available = ?",$bool);
    $bar = $foo->Load();
    $stuff = 'Brand of Pork is '.$bar['Bacon'].' combined with '.$bar['Eggs'].' eggs and '.$bar['Coffee'].' nectar for energy and heart failure.';

    return $stuff;

}

echo SweetStuff();

Problem is, I want to build the functionality in here to allow for a MySQL query which returns multiple results. What am I missing? I know it's staring me right in the face...

class db_connection
{
    private $conn;
    private $stmt;
    private $result;

    #Build a mysql connection
    public function __construct($host="HOST", $user="USER", $pass="PASS", $db="DB_NAME")
    {
        $this->conn = new mysqli($host, $user, $pass, $db);

        if(mysqli_connect_errno())
        {
            echo("Database connect Error : "
            . mysqli_connect_error());
        }
    }
    #return the connected connection
    public function getConnect()
    {
        return $this->conn;
    }
    #execute a prepared query without selecting
    public function execPreparedQuery($query, $params_r)
    {
        $stmt =  $this->conn->stmt_init();
        if (!$stmt->prepare($query))
        {
            echo("Error in $statement when preparing: "
            . mysqli_error($this->conn));
            return 0;
        }
        $types = '';
        $values = '';
        $index = 0;
        if(!is_array($params_r))
        $params_r = array($params_r);
        $bindParam = '$stmt->bind_param("';
        foreach($params_r as $param)
        {

            if (is_numeric($param)) {
                $types.="i";
            }
            elseif (is_float($param)) {
                $types.="d";
            }else{
                $types.="s";
            }
            $values .=  '$params_r[' . $index . '],';
            $index++;
        }
        $values = rtrim($values, ',');
        $bindParam .= $types . '", ' . $values . ');';      

        if (strlen($types) > 0)
        {
            //for debug
            //if(strpos($query, "INSERT") > 0)
            //var_dump($params_r);
            eval($bindParam);
        }

        $stmt->execute();       
        return $stmt;
    }
    #execute a prepared query
    public function queryPreparedQuery($query, $params_r)
    {
        $this->stmt = $this->execPreparedQuery($query, $params_r);
        $this->stmt->store_result();
        $meta = $this->stmt->result_metadata();
        $bindResult = '$this->stmt->bind_result(';
        while ($columnName = $meta->fetch_field()) {
            $bindResult .= '$this->result["'.$columnName->name.'"],';
        }
        $bindResult = rtrim($bindResult, ',') . ');';
        eval($bindResult);
    }
    #Load result
    public function Load(&$result = null)
    {       
        if (func_num_args() == 0)
        {
            $this->stmt->fetch();
            return $this->result;
        }
        else
        {
            $res = $this->stmt->fetch();
            $result = $this->result;
            return $res;
        }
    }

    #Load result
    public function Execute(&$result = null)
    {       
        if (func_num_args() == 0)
        {
            $this->stmt->fetch_array();
            return $this->result;
        }
        else
        {
            $res = $this->stmt->fetch_array();
            $result = $this->result;
            return $res;
        }
    }   

    private function bindParameters(&$obj, &$bind_params_r)
    {
        call_user_func_array(array($obj, "bind_param"), $bind_params_r);
    }

}

UPDATE

Got this to work with Patrick's help. Was able to find the following code with the help of this question , and with a few tweaks, it works beautifully. Added the following after the execute() statement in ExecPreparedQuery, returning an array at the very end instead of the single result:

    # these lines of code below return multi-dimentional/ nested array, similar to mysqli::fetch_all()
    $stmt->store_result();

    $variables = array();
    $data = array();
    $meta = $stmt->result_metadata();

    while($field = $meta->fetch_field())
        $variables[] = &$data[$field->name]; // pass by reference

    call_user_func_array(array($stmt, 'bind_result'), $variables);

    $i=0;
    while($stmt->fetch())
    {
        $array[$i] = array();
        foreach($data as $k=>$v)
            $array[$i][$k] = $v;
        $i++;
    }

    # close statement
    $stmt->close();

    return $array;

As a result of the altered code, I changed the call to interpret multidimensional array data rather than a single result, of course. Thanks again!

In your Execute function you are calling $this->stmt>fetch_array() .

That function only returns an array of a single row of the result set.

You probably want:

$this->stmt->fetch_all()

Update

To retrieve the entire result set from a prepared statement:

$this->stmt->store_result()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM