0

So my host doesn't have the mysqlnd driver installed for mysqli, so I'm unable to use the get_result() function (and it's not an option to install the mysqlnd driver). What are the alternatives to the following queries so that I don't use get_result()?

I know that I can use the following to get a single result from the database:

if ($stmt = $cxn->prepare("SELECT `count` FROM `numbers` WHERE `count_id` = ?")) {
    $stmt->bind_param('i', $count_id);
    $stmt->execute();
    $stmt->bind_result($count);
    $stmt->fetch();
    $stmt->close();
}

But what if I have to select several results from the database, loop through each, and get another result?

if ($stmt = $cxn->prepare("SELECT `count` FROM `numbers` WHERE `number` = ?")) {
    $stmt->bind_param('i', $number);
    $stmt->execute();
    $result = $stmt->get_result(); // uses get_result()
}

if ($result->num_rows) { // uses get_result()
    while ($row = $result->fetch_assoc()) { // uses get_result()
        if($stmt = $cxn->prepare("SELECT `value` FROM `values` WHERE `number` = ?")) {
            $stmt->bind_param('i', $row['count']);
            $stmt->execute();
            $stmt->bind_result($value);
            $stmt->fetch();
            $stmt->close();
        }
    }
}

I can't use this because some of the statements require get_result() which I'm unable to use.

What are my alternatives?

Walter
  • 71
  • 1
  • 7

2 Answers2

0

Try this,

if ($stmt = $cxn->prepare("SELECT `count` FROM `numbers` WHERE `count_id` = ?")) 
{

    $stmt->bind_param('i', $count_id);
    $stmt->execute();
    $result = $stmt->fetchAll();

        if ( count($result) ) 
        {

            foreach($result as $row) 
            {

                print_r($row);

            }
        } 
        else 
        {

            echo "Nothing Returned.";

        }
    }
Ant
  • 118
  • 3
0

I'm not entirely sure why this function isn't present in some installations of PHP but it's caught me out on a project, so I've implemented this almost-drop-in replacement. This function takes a 'mysqli_stmt' object as a parameter and will call the method on that object if it's present. If not, it makes use of this partial implementation (a number of methods I'm not using are missing) of the 'mysqli_result' class.

The 'convert_array' function handles all the array merging functionality associated with the '$mode' parameter.

function convert_array($assoc, $mode)
{
    $outarray = [];

    switch ($mode)
    {
        case MYSQLI_ASSOC:
            foreach($assoc as $key => $value)
            {       
                if (is_array($value))           
                    $outarray[$key] = convert_array($value, $mode);                                         
                else            
                    $outarray[$key] = $value;           
            }   
            return $outarray;
        case MYSQLI_NUM:
            $i = 0;
            foreach($assoc as $key => $value)
            {       
                if (is_array($value))           
                    $outarray[$i] = convert_array($value, $mode);                                           
                else            
                    $outarray[$i] = $value;         
                $i++;
            }   
            return $outarray;           
        case MYSQLI_BOTH:
            $i = 0;         
            foreach($assoc as $key => $value)
            {       
                if (is_array($value))                           
                    $outarray[$key] = $outarray[$i] = convert_array($value, $mode);                                         

                else            
                    $outarray[$key] = $outarray[$i] = $value;           
                $i++;
            }   
            return $outarray;
    }

    return $outarray;


}

//drop in replacement for the sometimes missing (depending on version) 'stmt->get_result'
class proxy_result
{
    public $current_field = 0;
    public $field_count = 0;
    public $lengths = 0;
    public $num_rows = 0;
    public $current_row = 0;
    public $type = 0;

    public $results = [];  

    function fetch_all ($resulttype = MYSQLI_NUM)
    {
        return convert_array($this->results, $resulttype);
    }


    //fetch row as associative array
    function fetch_assoc()
    {
        if ($this->current_row < $this->num_rows)
            return $this->results[$this->current_row++];
        else
            return null;        
    }

    function fetch_array($resulttype = MYSQLI_BOTH)
    {       
        return convert_array($this->fetch_assoc(), $resulttype);
    }  
};


function get_result( $stmt ) 
{
    if (method_exists ($stmt ,'get_result'))
    {
        return $stmt->get_result();
    }
    else
    {
        $RESULT = array();
        $stmt->store_result();
        for ( $i = 0; $i < $stmt->num_rows; $i++ ) 
        {
            $Metadata = $stmt->result_metadata();
            $PARAMS = array();
            while ( $Field = $Metadata->fetch_field() ) 
            {
                $PARAMS[] = &$RESULT[ $i ][ $Field->name ];
            }
            call_user_func_array( array( $stmt, 'bind_result' ), $PARAMS );
            $stmt->fetch();

            $result = new proxy_result();
            $result->num_rows = count($RESULT);
            $result->field_count = count($RESULT[0]);
            $result->results = $RESULT;

            //$RESULT->num_rows = count($RESULT);  
        }

        return $result;
    }   
}
Luther
  • 1,786
  • 3
  • 21
  • 38