Comment utiliser bind result () au lieu de get result () en php

je travaille sur un projet pour uni et j'ai utilisé le code suivant sur un testing server à get all devices d'une table basée sur un user_id :

public function getAllDevices($user_id) {
    $stmt = $this->conn->prepare("SELECT * FROM devices WHERE  primary_owner_id = ?");
    $stmt->bind_param("i", $user_id);
    $stmt->execute();
    $devices = $stmt->get_result();
    $stmt->close();
    return $devices;
}

cela a bien fonctionné sur mon serveur de test mais retourne cette erreur lors de la migration vers le serveur de projet de l'Université:

Call to undefined method mysqli_stmt::get_result()

un peu sur Google suggère d'utiliser bind_result() au lieu de get_result() mais je n'ai aucune idée comment faire ce all fields dans le tableau. La plupart des les exemples ne montrent que le retour one field

Toute aide serait grandement apprécié

3
demandé sur Ron Jobbins 2014-04-03 01:18:21

5 réponses

en supposant que vous ne pouvez pas utiliser get_result() et que vous voulez un tableau de périphériques, vous pouvez faire:

public function getAllDevices($user_id) {
    $stmt = $this->conn->prepare("SELECT device_id, device_name, device_info FROM devices WHERE  primary_owner_id = ?");
    $stmt->bind_param("i", $user_id);
    $stmt->execute();
    $stmt->bind_result($id, $name, $info);
    $devices = array();

    while($stmt->fetch()) {
        $tmp = array();
        $tmp["id"] = $id;
        $tmp["name"] = $name;
        $tmp["info"] = $info;
        array_push($devices, $tmp);
    }
    $stmt->close();
    return $devices;
}

Cela crée un tableau temporaire et stocke les données de chaque ligne, puis le pousse pour le tableau principal. Autant que je sache, vous ne pouvez pas utiliser SELECT * dans bind_result() . Au lieu de cela, vous devrez taper tous les champs que vous voulez après SELECT

5
répondu Josh Roberts 2014-04-02 22:58:03

maintenant, vous avez certainement compris l'idée de lier à plusieurs variables. Cependant, ne croyez pas les remontrances sur le fait de ne pas utiliser "SELECT *" avec bind_result(). Vous pouvez conserver vos déclarations" SELECT*"... même sur votre serveur vous demandant d'utiliser bind_result (), mais c'est un peu compliqué car vous devez utiliser call_user_func_array () de PHP pour passer un nombre arbitraire (à cause de "SELECT*") de paramètres à bind_result (). D'autres avant moi ont posté une fonction très pratique pour avoir fait cela ailleurs dans ces forums. Je l'inclus ici:

// Take a statement and bind its fields to an assoc array in PHP with the same fieldnames
function stmt_bind_assoc (&$stmt, &$bound_assoc) {
    $metadata = $stmt->result_metadata();
    $fields = array();
    $bound_assoc = array();

    $fields[] = $stmt;

    while($field = $metadata->fetch_field()) {
        $fields[] = &$bound_assoc[$field->name];
    }    
    call_user_func_array("mysqli_stmt_bind_result", $fields);
}

maintenant, pour utiliser ceci, nous faisons quelque chose comme:

function fetch_my_data() {
    $stmt = $conn->prepare("SELECT * FROM my_data_table");
    $stmt->execute();
    $result = array();
    stmt_bind_assoc($stmt, $row);
    while ($stmt->fetch()) {
         $result[] = array_copy($row);
    }
    return $result;
}

maintenant, fetch_my_data () retournera un tableau de tableaux associatifs... tout est prêt pour l'encodage de JSON ou autre.

c'est un peu rusé ce qui se passe, ici. stmt_bind_assoc () construit un tableau associatif vide à la référence que vous lui passez ($bound_assoc). Il utilise result_metadata() et fetch_field() pour obtenir une liste des champs retournés et que seule instruction dans la boucle while) crée un élément dans $bound_assoc fieldname et ajoute une référence dans le $tableau de champs. Le tableau $fields est ensuite passé à mysqli_stmt_bind_result. La partie la plus délicate est que aucune valeur réelle n'a été transmise dans $bound_assoc, mais . Toute la récupération des données de la requête se produit dans fetch_my_data (), comme vous pouvez le voir du fait que stmt_bind_assoc() est appelé avant le while($stmt->fetch()) .

il y a un hic, cependant: parce que la déclaration est liée aux références dans $bound_assoc, elles vont changer avec chaque $stmt->fetch() . Donc, vous devez faire une copie profonde de $row. Si vous ne le faites pas, toutes les des lignes dans votre tableau $result vont contenir la même chose: la dernière ligne retournée dans votre SELECT. Donc, j'utilise une petite fonction array_copy() que J'ai trouvée avec Google:

function array_copy( array $array ) {
    $result = array();
    foreach( $array as $key => $val ) {
        if( is_array( $val ) ) {
            $result[$key] = arrayCopy( $val );
        } elseif ( is_object( $val ) ) {
            $result[$key] = clone $val;
        } else {
            $result[$key] = $val;
        }
    }
    return $result;
}
2
répondu Jemenake 2014-08-31 21:29:23

pour utiliser bind_result() vous ne pouvez pas utiliser des requêtes que SELECT * .

à la place, vous devez sélectionner des noms de table individuels, puis lier les résultats dans le même ordre. voici un exemple:

$stmt = $mysqli->prepare("SELECT foo, bar, what, why FROM table_name WHERE id = ?");
$stmt->bind_param("i", $id);
if($stmt->execute()) {
    $stmt->bind_result($foo, $bar, $what, $why);
    if($stmt->fetch()) {
        $stmt->close();
    }else{
        //error binding result(no rows??)
    }
}else{
    //error with query
}
1
répondu r3wt 2014-04-02 21:40:30

votre question suggère que vous avez MySQL Native driver (MySQLnd) installé sur votre serveur local, mais MySQLnd est absent sur le serveur de projet de l'école. Parce que get_result() nécessite MySQLnd.

par conséquent, si vous voulez toujours utiliser get_result() au lieu de bind_result() sur le serveur de projet de l'école, alors vous devriez installer MySQLnd sur le serveur de projet de l'école.

1
répondu Ugokoli 2017-04-19 07:37:23

get_result() est maintenant seulement disponible en PHP en installant le pilote MySQL native (mysqlnd). Dans certains environnements, il peut ne pas être possible ou souhaitable d'installer mysqlnd.

nonobstant, vous pouvez toujours utiliser mysqli pour faire des requêtes " select*", et obtenir les résultats avec les noms de champ - bien que ce soit légèrement plus compliqué que d'utiliser get_result() , et implique l'utilisation de la fonction call_user_func_array() de php. Voir l'exemple ci-dessous qui fait une simple requête " select*", et affiche les résultats (avec les noms de colonnes) dans une table HTML:

$maxaccountid=100;
$sql="select * from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);      
$stmt->bind_param('i', $maxaccountid); 
$stmt->execute();
print "<table border=1>";
print "<thead><tr>";   
$i=0;
$meta = $stmt->result_metadata();
$query_data=array();  
while ($field = $meta->fetch_field()) { 
  print "<th>" . $field->name . "</th>";
  $var = $i;
  $$var = null; 
  $query_data[$var] = &$$var; 
  $i++;    
}
print "</tr></thead>";
$r=0;
call_user_func_array(array($stmt,'bind_result'), $query_data); 
while ($stmt->fetch()) {                   
  print "<tr>";
  for ($i=0; $i<count($query_data); $i++) { 
    print "<td>" .  $query_data[$i] . "</td>"; 
  }
  print "</tr>";
  $r++;        
}
print "</table>";
$stmt->close();
print $r . " Records<BR>";
0
répondu mti2935 2016-07-20 21:23:16