简体   繁体   中英

PHP MySQLi Prepared Statement: Fetch Not Returning Results for Joins

I forget where I copied it from (I think a user posted it on php.net) but this function for fetching results of prepared and normal MySQLi statements is not returning any results when used with statements that contain a simple INNER JOIN, at least the one I tried:

    function fetch($result){   
    $array = array();           
    if($result instanceof mysqli_stmt){
        $result->store_result();
        $variables = array();
        $data = array();
        $meta = $result->result_metadata();                 
        while($field = $meta->fetch_field()){                   
            $variables[] = &$data[$field->name];
        }               
        call_user_func_array(array($result, 'bind_result'), $variables);
        $i=0;                               
        while($result->fetch()){                                    
            $array[$i] = array();
            foreach($data as $k=>$v)
            $array[$i][$k] = $v;
            $i++;                   
        }               
    }elseif($result instanceof mysqli_result){
        while($row = $result->fetch_assoc())
        $array[] = $row;
    }           
    return $array;
}

I've been trying to use it like so (all these functions are methods of the class $database):

    function query($str, $values){                              
    if($stmt=$this->sql->prepare($str)){                    
        $types=$this->castArrayAsString($values); //returns a string of $values's types for bind_params             
        array_unshift($values, $types);         
        call_user_func_array(array(&$stmt, 'bind_param'), $this->makeValuesReferenced($values));                        
        $stmt->execute();
        $result=$this->fetch($stmt); //the function I'm having problems with                                                                            
        if(empty($result)){                                     
            $return=true;                   
        }else{
            $return=$result;
        }       
        $stmt->close();         
    }else{
        echo $this->sql->error;
        $return=false;  
    }                       
    return $return;             
}

This returns nothing:

$list=$database->query("SELECT a.field1, b.field2 FROM table1 AS a INNER JOIN table2 AS b ON a.id_table2=b.id WHERE a.someid=?", array($someid));

This works fine:

$list=$database->query("SELECT field1, field2 FROM table1 WHERE someid=?", array($someid));

If I print out the meta data from fetching the result, it shows that fields are selected, etc, but still gives no final results in the fetch() func.

Any help is appreciated,

Thanks

EDIT HERE IS THE WHOLE CLASS

<?php

class database{

    var $HOST="xx.xx.xx.xxx";   
    var $USER="xxxxxxxxxxx";    
    var $PASS='xxxxxxxxxx';

    var $DATABASE="my_database";

    var $sql;

    function database(){            
        $this->sql=new mysqli($this->HOST, $this->USER, $this->PASS, $this->DATABASE);              
        if($this->sql->connect_errno){
            echo "ERROR - No MySQL connection: ".$mysqli->connect_error;
            exit;
        }                   
    }

    function query($str, $values){                                          
        if($stmt=$this->sql->prepare($str)){                            
            $types=$this->castArrayAsString($values);               
            array_unshift($values, $types);         
            call_user_func_array(array(&$stmt, 'bind_param'), $this->makeValuesReferenced($values));                                
            $stmt->execute();                               
            $result=$this->fetch($stmt);                                                                                        
            if(empty($result)){                                     
                $return=true;                   
            }else{
                $return=$result;
            }                       
            $stmt->close();         
        }else{
            echo $this->sql->error;
            $return=false;  
        }                       
        return $return;             
    }

    function fetch($result){   
        $array = array();           
        if($result instanceof mysqli_stmt){
            $result->store_result();
            $variables = array();
            $data = array();
            $meta = $result->result_metadata();                 
            while($field = $meta->fetch_field()){                   
                $variables[] = &$data[$field->name];
            }               
            call_user_func_array(array($result, 'bind_result'), $variables);
            $i=0;                               
            while($result->fetch()){                                    
                $array[$i] = array();
                foreach($data as $k=>$v)
                $array[$i][$k] = $v;
                $i++;                   
            }               
        }elseif($result instanceof mysqli_result){
            while($row = $result->fetch_assoc())
            $array[] = $row;
        }           
        return $array;
    }

    function close(){
        $this->sql->close();    
    }

    function castArrayAsString($array){         
        $types="";
        foreach($array as $key => $value) {              
            if(is_numeric($value)){
                if(is_float($value)){
                    $types.="d";
                }else{
                    $types.="i";
                }                   
            }else{
                $types.="s";
            }                        
        }           
        return $types;  
    }

    function makeValuesReferenced($arr){
        $refs=array();
        foreach($arr as $key => $value){
            $refs[$key] = &$arr[$key];
        }
        return $refs;       
    }

}

$database=new database;

?>

The query that returns 0 result set is doing an 'inner-join', which means that the source table and the target table must share the same value for the columns being linked against in the query (in this case a.id_table2 and b.id). Chances are you don't have any matching values so you are getting a 0 result set. Try a left outer join.


Try the following and see if your results are returned:

    "SELECT a.field1, b.field2 FROM table1 AS a INNER JOIN table2 AS b ON a.id_table2=b.id WHERE a.someid = :someId"

    $dbo = new Database();

    $stmt = $dbo->sql->prepare($sql);

    $stmt->bindValue(':someId', $someId, PDO::PARAM_INT);

    $stmt->execute();

    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        var_dump($row);
    }

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