web-dev-qa-db-fra.com

Comment faire écho à une instruction préparée par MySQLi?

Je joue avec MySQLi en ce moment, essayant de comprendre comment tout cela fonctionne. Dans mes projets en cours, j'aime toujours faire écho à une chaîne de requête lors du codage, juste pour m'assurer que tout est correct et déboguer rapidement mon code. Mais ... comment puis-je faire cela avec une instruction MySQLi préparée?

Exemple:

$id = 1;
$baz = 'something';

if ($stmt = $mysqli->prepare("SELECT foo FROM bar WHERE id=? AND baz=?")) {
  $stmt->bind_param('is',$id,$baz);
  // how to preview this prepared query before acutally executing it?
  // $stmt->execute();
}

J'ai parcouru cette liste ( http://www.php.net/mysqli ) mais sans aucune chance.


ÉDITER

Eh bien, si ce n'est pas possible depuis MySQLi, je vais peut-être m'en tenir à quelque chose comme ceci:

function preparedQuery($sql,$params) {
  for ($i=0; $i<count($params); $i++) {
    $sql = preg_replace('/\?/',$params[$i],$sql,1);
  }
  return $sql;
}

$id = 1;
$baz = 'something';

$sql = "SELECT foo FROM bar WHERE id=? AND baz=?";

echo preparedQuery($sql,array($id,$baz));

// outputs: SELECT foo FROM bar WHERE id=1 AND baz=something

Loin d'être parfait évidemment, car c'est encore assez redondant - quelque chose que je voulais éviter - et cela ne me donne pas non plus une idée de ce qui est fait avec les données de MySQLi. Mais je suppose que de cette façon, je peux rapidement voir si toutes les données sont présentes et au bon endroit, et cela me fera gagner du temps par rapport à l'ajustement dans les variables manuellement dans la requête - cela peut être pénible avec de nombreux vars.

45
Alec

Je ne pense pas que vous puissiez - du moins pas de la manière que vous espériez. Vous devrez soit créer la chaîne de requête vous-même et l'exécuter (c'est-à-dire sans utiliser d'instruction), soit rechercher ou créer un wrapper qui prend en charge cette fonctionnalité. Celui que j'utilise est Zend_Db , et voici comment je le ferais:

$id = 5;
$baz = 'shazam';
$select = $db->select()->from('bar','foo')
                       ->where('id = ?', $id)
                       ->where('baz = ?', $baz); // Zend_Db_Select will properly quote stuff for you
print_r($select->__toString()); // prints SELECT `bar`.`foo` FROM `bar` WHERE (id = 5) AND (baz = 'shazam')
10
karim79

J'ai eu du mal avec celui-ci dans le passé. Donc, pour contourner cela, j'ai écrit une petite fonction pour construire le SQL pour moi en fonction du SQL, des drapeaux et des variables.

//////////// Test Data //////////////
$_GET['filmID'] = 232;
$_GET['filmName'] = "Titanic";
$_GET['filmPrice'] = 10.99;

//////////// Helper Function //////////////
function debug_bind_param(){
    $numargs = func_num_args();
    $numVars = $numargs - 2;
    $arg2 = func_get_arg(1);
    $flagsAr = str_split($arg2);
    $showAr = array();
    for($i=0;$i<$numargs;$i++){
        switch($flagsAr[$i]){
        case 's' :  $showAr[] = "'".func_get_arg($i+2)."'";
        break;
        case 'i' :  $showAr[] = func_get_arg($i+2);
        break;  
        case 'd' :  $showAr[] = func_get_arg($i+2);
        break;  
        case 'b' :  $showAr[] = "'".func_get_arg($i+2)."'";
        break;  
        }
    }
    $query = func_get_arg(0);
    $querysAr = str_split($query);
    $lengthQuery = count($querysAr);
    $j = 0;
    $display = "";
    for($i=0;$i<$lengthQuery;$i++){
        if($querysAr[$i] === '?'){
            $display .= $showAr[$j];
            $j++;   
        }else{
            $display .= $querysAr[$i];
        }
    }
    if($j != $numVars){
        $display = "Mismatch on Variables to Placeholders (?)"; 
    }
    return $display;
}

//////////// Test and echo return //////////////

echo debug_bind_param("SELECT filmName FROM movies WHERE filmID = ? AND filmName = ? AND price = ?", "isd", $_GET['filmID'], $_GET['filmName'], $_GET['filmPrice']);

J'ai également créé un petit outil en ligne pour vous aider.

Mysqli Préparer le vérificateur d'instructions

6
mustbebuilt

Il suffit de le mettre à mort et de sortir la dernière requête exécutée. La gestion des erreurs doit vous fournir des informations utiles que vous pouvez utiliser pour corriger votre requête.

4
Langerz

Vous pouvez activer les requêtes de journal sur le serveur mysql. Exécutez simplement la commande:

sql> SHOW VARIABLES LIKE "general_log%";
sql> SET GLOBAL general_log = 'ON';

Et regardez les requêtes dans le fichier journal. Après le test, fermez la session:

sql> SET GLOBAL general_log = 'OFF';
0
alchemist