53 Stimmen

Wie kann man eine MySQLi-Vorbereitungserklärung echo?

Ich spiele im Moment mit MySQLi herum, ich versuche herauszufinden, wie alles funktioniert. In meinen aktuellen Projekten gebe ich beim Codieren immer gerne einen Abfrage-String aus, nur um sicherzustellen, dass alles korrekt ist, und um meinen Code schnell zu debuggen. Aber... wie kann ich das mit einer vorbereiteten MySQLi-Anweisung machen?

Beispiel:

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

if ($stmt = $mysqli->prepare("SELECT foo FROM bar WHERE id=? AND baz=?")) {
  $stmt->bind_param('is',$id,$baz);
  // wie kann ich diese vorbereitete Abfrage vor der eigentlichen Ausführung anzeigen?
  // $stmt->execute();
}

Ich habe diese Liste durchgesehen (http://www.php.net/mysqli), aber ohne Erfolg.

EDIT

Nun, wenn es nicht möglich ist, dies von innerhalb von MySQLi aus zu tun, bleibe ich vielleicht bei etwas wie diesem:

function preparedQuery($sql,$params) {
  for ($i=0; $i

`

Weit davon entfernt, perfekt zu sein, da es immer noch ziemlich redundant ist - etwas, das ich vermeiden wollte - und es gibt mir auch keine Vorstellung davon, was MySQLi mit den Daten macht. Aber ich denke, auf diese Weise kann ich schnell sehen, ob alle Daten vorhanden sind und sich am richtigen Ort befinden, und es wird mir etwas Zeit ersparen im Vergleich dazu, die Variablen manuell in die Abfrage einzufügen - das kann bei vielen Variablen mühsam sein.

`

12voto

karim79 Punkte 333786

Ich glaube nicht, dass du das kannst - zumindest nicht auf die Art und Weise, wie du es gehofft hast. Du müsstest entweder die Abfragezeichenfolge selbst erstellen und ausführen (d.h. ohne die Verwendung eines Statements), oder eine Wrapper suchen oder erstellen, der diese Funktionalität unterstützt. Den, den ich benutze, ist Zend_Db, und so würde ich es machen:

$id = 5;
$baz = 'shazam';
$select = $db->select()->from('bar','foo')
                       ->where('id = ?', $id)
                       ->where('baz = ?', $baz); // Zend_Db_Select wird Zeug richtig für dich zitieren
print_r($select->__toString()); // gibt SELECT `bar`.`foo` FROM `bar` WHERE (id = 5) AND (baz = 'shazam') aus

9voto

mustbebuilt Punkte 409

Ich habe in der Vergangenheit mit diesem Problem gekämpft. Um es zu umgehen, habe ich eine kleine Funktion geschrieben, die den SQL für mich basierend auf dem SQL, den Flags und Variablen erstellt.

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

//////////// Hilfsfunktion //////////////
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 = "Unstimmigkeit bei Variablen zu Platzhaltern (?)";
    }
    return $display;
}

//////////// Test und echo return //////////////

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

Ich habe auch ein kleines Online-Tool erstellt, um zu helfen.

Mysqli Prepare Statement Checker

6voto

Noah Heck Punkte 496

Ich habe dieses Projekt kürzlich aktualisiert, um die Integration von Composer, Unittesting und eine verbesserte Behandlung der Akzeptanz von Argumenten per Referenz (dies erfordert ein Update auf php 5.6) einzuschließen.


Als Reaktion auf eine Anfrage, die ich zu einem Projekt erhalten habe, das ich erstellt habe, um dieses Problem mit PDO zu lösen, habe ich eine Erweiterung für mysqli auf github erstellt, die anscheinend Ihr Problem löst:

https://github.com/noahheck/E_mysqli

Es handelt sich um eine Reihe von Klassen, die die nativen Klassen mysqli und mysqli_stmt erweitern, um es Ihnen zu ermöglichen, ein Beispiel der Abfrage an den db-Server anzuzeigen, indem die gebundenen Parameter in die vorbereitete Abfrage interpoliert werden und Ihnen dann Zugriff auf den resultierenden Abfragestring als neue Eigenschaft des stmt-Objekts geben:

$mysqli  = new E_mysqli($dbHost, $dbUser, $dbPass, $dbName);

$query = "UPDATE registration SET name = ?, email = ? WHERE entryId = ?";

$stmt = $mysqli->prepare($query);

$stmt->bindParam("ssi", $_POST['name'], $_POST['email'], $_POST['entryId']);

$stmt->execute();

echo $stmt->fullQuery;

Ergebnis:

UPDATE registration SET name = 'Sue O\'reilly', email = 'sue.o@example.com' WHERE entryId = 5569

Beachten Sie, dass die Werte in der fullQuery entsprechend dem Character Set auf dem db-Server angemessen escaped sind, was diese Funktionalität für z.B. Log-Dateien, Backups usw. geeignet machen sollte.

Es gibt einige Einschränkungen bei der Verwendung dieses Tools, die im ReadMe des github-Projekts erläutert sind, aber insbesondere für Entwicklung, Lernen und Testen sollte dies einige nützliche Funktionalitäten bieten.

Wie ich im github-Projekt erläutert habe, habe ich keine praktischen Erfahrungen mit der mysqli-Erweiterung, und dieses Projekt wurde auf Anfrage von Benutzern seines Schwesterprojekts erstellt, daher wäre jedes Feedback von Entwicklern, die dies in der Produktion verwenden, sehr willkommen.

Haftungsausschluss - Wie gesagt, ich habe diese Erweiterung erstellt.

3voto

Langerz Punkte 47

Setzen Sie es einfach auf "die" und geben Sie die zuletzt ausgeführte Abfrage aus. Die Fehlerbehandlung sollte Ihnen aussagekräftige Informationen geben, die Sie verwenden können, um Ihre Abfrage zu korrigieren.

-1voto

alchemist Punkte 17

Sie können Abfrageprotokolle auf dem MySQL-Server aktivieren. Führen Sie einfach den Befehl aus:

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

Und beobachten Sie Abfragen in der Protokolldatei. Nach dem Testen das Protokoll ausschalten:

sql> SET GLOBAL general_log = 'OFF';

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X