#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. Существует МНОГО сложной логики вокруг параметров, связанных с запросом, что заставляет меня полагать, что параметр привязан неправильно. Я собираюсь быстро провести тестирование и опубликовать свои результаты.