Reputation: 147
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;
?>
Upvotes: 0
Views: 2293
Reputation: 19999
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);
}
Upvotes: 0