Подготовленная инструкция PHP MySQLi: выборка не возвращает результатов для объединений

#php #mysqli #prepared-statement

#php #mysqli #подготовленный оператор

Вопрос:

Я забыл, откуда я его скопировал (я думаю, что пользователь разместил его на php.net ) но эта функция для извлечения результатов подготовленных и обычных операторов MySQLi не возвращает никаких результатов при использовании с операторами, которые содержат простое ВНУТРЕННЕЕ СОЕДИНЕНИЕ, по крайней мере, то, которое я пробовал:

     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[] = amp;$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;
}
  

Я пытался использовать это так (все эти функции являются методами класса $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(amp;$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;             
}
  

Это ничего не возвращает:

 $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));
  

Это работает нормально:

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

Если я распечатываю метаданные из выборки результата, это показывает, что поля выбраны и т.д., Но по-прежнему не дает окончательных результатов в функции fetch().

Любая помощь приветствуется,

Спасибо

РЕДАКТИРОВАТЬ ВОТ ВЕСЬ КЛАСС

 <?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(amp;$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[] = amp;$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] = amp;$arr[$key];
        }
        return $refs;       
    }

}

$database=new database;
  

?>

Ответ №1:

Запрос, который возвращает набор результатов 0, выполняет ‘inner-join’, что означает, что исходная таблица и целевая таблица должны использовать одно и то же значение для столбцов, с которыми связаны в запросе (в данном случае.id_table2 и b.id ). Скорее всего, у вас нет совпадающих значений, поэтому вы получаете набор результатов 0. Попробуйте левое внешнее соединение.


Попробуйте следующее и посмотрите, будут ли возвращены ваши результаты:

     "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);
    }
  

Комментарии:

1. Значения.id_table2 и b.id соответствует, и я попробовал внешнее объединение с теми же результатами. Чтобы убедиться, что мой SQL не ошибся, я проверил его в phpMyAdmin, где он без проблем вернул желаемые результаты.

2. Похоже, дело не в коде, проблема в самом запросе. Можете ли вы опубликовать фрагмент вашей схемы?

3. Конечно, table1: id (int, autoinc), id_table2 (int), field1 (varchar), field2 (varchar) table2: id (int, autoinc), field1 (varchar), field2 (varchar) Опять же, я попробовал точный запрос, с которым у меня возникли проблемы, в SQL-запросе, и он работает, но не в приведенном выше коде, что заставляет меня полагать, что это код. Возможно, что-то связано с использованием ON . Я опубликую весь класс для тестирования.

4. Хорошо, извините, я не понял, что sql работает из командной строки, но не в коде, как написано. Хорошо, итак, sql работает, просто нужно выяснить, почему код не работает.

5. Существует МНОГО сложной логики вокруг параметров, связанных с запросом, что заставляет меня полагать, что параметр привязан неправильно. Я собираюсь быстро провести тестирование и опубликовать свои результаты.