Wie debugge ich PDO-Datenbankabfragen?

140

Vor dem Wechsel zu PDO habe ich SQL-Abfragen in PHP durch Verketten von Zeichenfolgen erstellt. Wenn ich einen Datenbanksyntaxfehler habe, kann ich einfach die endgültige SQL-Abfragezeichenfolge wiederholen, sie selbst in der Datenbank ausprobieren und optimieren, bis ich den Fehler behoben habe, und diese dann wieder in den Code einfügen.

Vorbereitete PDO-Anweisungen sind schneller und besser und sicherer, aber eines stört mich: Ich sehe die endgültige Abfrage nie, wenn sie an die Datenbank gesendet wird. Wenn ich Fehler bezüglich der Syntax in meinem Apache-Protokoll oder meiner benutzerdefinierten Protokolldatei erhalte (ich protokolliere Fehler innerhalb eines catchBlocks), kann ich die Abfrage, die sie verursacht hat, nicht sehen.

Gibt es eine Möglichkeit, die vollständige SQL-Abfrage zu erfassen, die vom PDO an die Datenbank gesendet und in einer Datei protokolliert wird?

Nathan Long
quelle
4
Es ist in einer Datei protokolliert : /var/log/mysql/*. PDO-gebundene Parameter können keine Syntaxfehler verursachen. Sie benötigen daher nur die vorbereitete SQL-Abfrage.
Xeoncross
1
Siehe den Code unter stackoverflow.com/questions/210564/… (nicht in der akzeptierten Antwort). Nicht, dass ein paar Updates veröffentlicht wurden.
Mawg sagt, Monica am
1
Einfache einzeilige über Composer: github.com/panique/pdo-debug
Sliq
2
Xeoncross 'Antwort hat mir geholfen. In diesem Artikel wird erläutert, wie Sie diese Funktion aktivieren. Bei vielen Serverinstallationen ist dies standardmäßig deaktiviert. pontikis.net/blog/how-and-when-to-enable-mysql-logs
mrbinky3000
2
Versuchen Sie mitvar_dump($pdo_instance->debugDumpParams())
Daniel Petrovaliev

Antworten:

99

Du sagst das :

Ich sehe die endgültige Abfrage nie, wenn sie an die Datenbank gesendet wird

Nun, tatsächlich gibt es bei Verwendung vorbereiteter Anweisungen keine " endgültige Abfrage " :

  • Zunächst wird eine Anweisung an die DB gesendet und dort vorbereitet
    • Die Datenbank analysiert die Abfrage und erstellt eine interne Darstellung davon
  • Wenn Sie Variablen binden und die Anweisung ausführen, werden nur die Variablen an die Datenbank gesendet
    • Und die Datenbank "injiziert" die Werte in ihre interne Darstellung der Anweisung


Um Ihre Frage zu beantworten:

Gibt es eine Möglichkeit, die vollständige SQL-Abfrage zu erfassen, die vom PDO an die Datenbank gesendet und in einer Datei protokolliert wird?

Nein: Da es nirgendwo eine " vollständige SQL-Abfrage " gibt, gibt es keine Möglichkeit, diese zu erfassen.


Das Beste, was Sie zu Debugging-Zwecken tun können, ist, eine "echte" SQL-Abfrage "neu zu konstruieren", indem Sie die Werte in die SQL-Zeichenfolge der Anweisung einfügen.

Was ich normalerweise in solchen Situationen mache, ist:

  • Geben Sie den SQL-Code, der der Anweisung entspricht, mit Platzhaltern wieder
  • und verwenden Sie var_dump (oder ein Äquivalent) direkt danach, um die Werte der Parameter anzuzeigen
  • Dies ist im Allgemeinen ausreichend, um einen möglichen Fehler anzuzeigen, selbst wenn Sie keine "echte" Abfrage haben, die Sie ausführen können.

Das ist beim Debuggen nicht besonders gut - aber das ist der Preis für vorbereitete Anweisungen und die damit verbundenen Vorteile.

Pascal MARTIN
quelle
1
Tolle Erklärung - danke. Anscheinend hatte ich nur unscharfe Vorstellungen davon, wie das funktioniert. Ich nehme an, wenn die Anweisung vorbereitet ist, enthält das resultierende Objekt einen Hash oder eine numerische ID, die mit den Parametern zum Einstecken an die Datenbank zurückgesendet werden kann.
Nathan Long
Bitte :-) ;;; Ich weiß nicht, wie dies im Detail implementiert wird, aber ich nehme an, es ist so etwas - das Ergebnis ist sowieso genau so ;;; Das ist eines der schönen Dinge bei vorbereiteten Anweisungen: Wenn Sie dieselbe Abfrage häufig ausführen müssen, wird sie nur einmal an die Datenbank gesendet und vorbereitet: Bei jeder Ausführung werden nur die Daten gesendet.
Pascal MARTIN
1
Update: Aaron Patterson erwähnte auf der Railsconf 2011, dass er Rails besser vorbereitete Aussagen hinzugefügt hat, dass der Nutzen in PostgreSQL jedoch viel größer ist als in MySQL. Er sagte, dies liege daran, dass MySQL den Abfrageplan erst dann erstellt, wenn Sie die vorbereitete Abfrage ausführen.
Nathan Long
85

Im Datenbankprotokoll suchen

Obwohl Pascal MARTIN richtig ist, dass PDO nicht die gesamte Abfrage auf einmal an die Datenbank sendet , konnte ich aufgrund des Vorschlags von Ryeguy , die Protokollierungsfunktion der Datenbank zu verwenden, die vollständige Abfrage als von der Datenbank zusammengestellt und ausgeführt sehen.

So geht's: (Diese Anweisungen gelten für MySQL auf einem Windows-Computer - Ihr Kilometerstand kann variieren.)

  • Fügen Sie my.iniunter dem [mysqld]Abschnitt einen logBefehl hinzu, zlog="C:\Program Files\MySQL\MySQL Server 5.1\data\mysql.log"
  • Starten Sie MySQL neu.
  • Jede Abfrage in dieser Datei wird protokolliert.

Diese Datei wächst schnell. Löschen Sie sie daher unbedingt und deaktivieren Sie die Protokollierung, wenn Sie mit dem Testen fertig sind.

Nathan Long
quelle
1
Nur eine Anmerkung - ich musste den Schrägstrichen in my.ini entkommen. Mein Eintrag sah also ungefähr so ​​aus wie log = "C: \\ temp \\ MySQL \\ mysql.log".
Jim
4
Dies kann je nach Einstellung von funktionieren PDO::ATTR_EMULATE_PREPARES. Siehe diese Antwort für weitere Informationen: stackoverflow.com/questions/10658865/#answer-10658929
webbiedave
23
Ich hasse PDO deswegen.
Salman
1
@webbiedave - oh, wow! Ihre verknüpfte Antwort impliziert, dass meine Antwort nur funktioniert, wenn PDO nicht optimal funktioniert, sondern die gesamte Abfrage zur Abwärtskompatibilität mit der alten Version von MySQL oder einem alten Treiber gesendet wird. Interessant.
Nathan Long
13
In MySQL 5.5+ benötigen Sie general_logstatt log. Siehe dev.mysql.com/doc/refman/5.5/en/query-log.html
Adrian Macneil
17

Sicher können Sie in diesem Modus debuggen. Fügen Sie {{ PDO::ATTR_ERRMODE }} einfach vor Ihrer Abfrage eine neue Zeile hinzu, dann werden die Debug-Zeilen angezeigt.

$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$db->query('SELECT *******');  
Saud Alfadhli
quelle
Sie würden jedoch nicht anrufen, ->querywenn Sie vorbereitete Anweisungen verwenden?
EoghanM
17

Wahrscheinlich möchten Sie debugDumpParams () für das Anweisungshandle verwenden. Sie können dies jederzeit ausführen, nachdem Sie Werte an die vorbereitete Abfrage gebunden haben ( execute()die Anweisung ist nicht erforderlich ).

Die vorbereitete Anweisung wird nicht für Sie erstellt, es werden jedoch Ihre Parameter angezeigt.

Fidschiaaron
quelle
2
Das einzige Problem ist, dass es das Debug ausgibt, anstatt es intern zu speichern, ohne es zu "echoen". Ich kann es nicht so protokollieren.
Ricardo Martins
3
Sie können die Ausgabepufferung (ob_start () ...) verwenden, um die Ausgabe zu speichern und zu protokollieren.
Cranio
bugs.php.net/bug.php?id=52384 behoben in 7.1 können Sie die Werte sehen :) etwas spät, aber es ist php
Sander Visser
12

Ein alter Beitrag, aber vielleicht findet jemand dies nützlich;

function pdo_sql_debug($sql,$placeholders){
    foreach($placeholders as $k => $v){
        $sql = preg_replace('/:'.$k.'/',"'".$v."'",$sql);
    }
    return $sql;
}
nicht wieder
quelle
1
Eine ähnliche Funktion, die auch numerische Parameter verarbeiten kann, finden Sie in meiner Antwort (dank eines Kommentators auf php.net).
Matt Browne
9

Hier ist eine Funktion, um zu sehen, wie effektiv SQL sein wird. Dies geht aus einem Kommentar von "Mark" auf php.net hervor :

function sql_debug($sql_string, array $params = null) {
    if (!empty($params)) {
        $indexed = $params == array_values($params);
        foreach($params as $k=>$v) {
            if (is_object($v)) {
                if ($v instanceof \DateTime) $v = $v->format('Y-m-d H:i:s');
                else continue;
            }
            elseif (is_string($v)) $v="'$v'";
            elseif ($v === null) $v='NULL';
            elseif (is_array($v)) $v = implode(',', $v);

            if ($indexed) {
                $sql_string = preg_replace('/\?/', $v, $sql_string, 1);
            }
            else {
                if ($k[0] != ':') $k = ':'.$k; //add leading colon if it was left out
                $sql_string = str_replace($k,$v,$sql_string);
            }
        }
    }
    return $sql_string;
}
Matt Browne
quelle
Warum verwendet "Mark" Doppelpunkt vor $ k in str_replace(":$k" ....? Assoziative Indizes haben es bereits im Array $ params.
Alan
Gute Frage ... das könnte es erklären: stackoverflow.com/questions/9778887/… . Persönlich habe ich diese Funktion zum Debuggen von Doctrine-Abfragen verwendet, und ich denke, Doctrine verwendet nummerierte statt benannte Parameter, sodass ich dieses Problem nicht bemerkt habe. Ich habe die Funktion so aktualisiert, dass sie jetzt entweder mit oder ohne führende Doppelpunkte funktioniert.
Matt Browne
beachten Sie , dass diese Lösung ersetzt :name_longmit :name. Zumindest wenn :namevorher kommt :name_long. Von MySQL vorbereitete Anweisungen können damit korrekt umgehen. Lassen Sie sich also nicht verwirren.
Zim84
8

Nein. PDO-Abfragen werden auf der Clientseite nicht vorbereitet. PDO sendet einfach die SQL-Abfrage und die Parameter an den Datenbankserver. Die Datenbank ist das, was die Substitution (der ?'s) bewirkt . Sie haben zwei Möglichkeiten:

  • Verwenden Sie die Protokollierungsfunktion Ihrer Datenbank (aber selbst dann wird sie normalerweise als zwei separate Anweisungen angezeigt (dh "nicht endgültig"), zumindest bei Postgres).
  • Geben Sie die SQL-Abfrage und die Parameter aus und setzen Sie sie selbst zusammen
Ryeguy
quelle
Ich hätte nie gedacht, das DB-Protokoll zu überprüfen. Ich stöbere im MySQL-Verzeichnis herum und sehe keine Protokolldateien, aber vielleicht ist die Protokollierung eine Option, die ich irgendwo aktivieren muss.
Nathan Long
Ja, du musst es einschalten. Ich kenne die Details nicht, aber standardmäßig werden nicht alle Abfragen protokolliert.
Ryeguy
5

Über die Fehleranzeige wurde fast nichts gesagt, außer Fehlerprotokolle überprüfen, aber es gibt eine ziemlich hilfreiche Funktion:

<?php
/* Provoke an error -- bogus SQL syntax */
$stmt = $dbh->prepare('bogus sql');
if (!$stmt) {
    echo "\PDO::errorInfo():\n";
    print_r($dbh->errorInfo());
}
?>

( Quelllink )

Es ist klar, dass dieser Code geändert werden kann, um als Ausnahmemeldung oder andere Art der Fehlerbehandlung verwendet zu werden

Zippp
quelle
2
Das ist falsch. PDO ist intelligent genug, um diesen Code unbrauchbar zu machen. Sagen Sie ihm einfach, er soll Ausnahmen bei Fehlern auslösen. PHP erledigt den Rest viel besser als diese eingeschränkte Funktion. Auch bitte , lernen nicht alle Fehler direkt in den Browser zu drucken. Es gibt bessere Wege.
Ihr gesunder Menschenverstand
3
Das ist die offizielle Dokumentation, und natürlich wollte niemand diesen Fehler in der Produktion drucken. Auch dies ist ein Beispiel von der offiziellen Website (php.net), siehe den Link unter dem Codebeispiel. Und sicher ist es viel besser, zusätzliche Parameter $ db-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION) innerhalb der PDO-Instanziierung zu verwenden, aber leider konnten Sie keinen Zugriff auf diesen Code haben
Zippp
4

Zum Beispiel haben Sie diese pdo-Anweisung:

$query="insert into tblTest (field1, field2, field3)
values (:val1, :val2, :val3)";
$res=$db->prepare($query);
$res->execute(array(
  ':val1'=>$val1,
  ':val2'=>$val2,
  ':val3'=>$val3,
));

Jetzt können Sie die ausgeführte Abfrage erhalten, indem Sie ein Array wie folgt definieren:

$assoc=array(
  ':val1'=>$val1,
  ':val2'=>$val2,
  ':val3'=>$val3,
);
$exQuery=str_replace(array_keys($assoc), array_values($assoc), $query);
echo $exQuery;
Alireza
quelle
1
Hat für mich gearbeitet. Sie haben einen Fehler im zweiten Codebeispiel: ));sollte sein );(nur eine runde Klammer).
Jasom Dotnet
2

Durch die Suche im Internet fand ich dies als akzeptable Lösung. Anstelle von PDO wird eine andere Klasse verwendet, und PDO-Funktionen werden durch magische Funktionsaufrufe aufgerufen. Ich bin nicht sicher, ob dies zu ernsthaften Leistungsproblemen führt. Es kann jedoch verwendet werden, bis PDO eine sinnvolle Protokollierungsfunktion hinzugefügt wird.

Gemäß diesem Thread können Sie einen Wrapper für Ihre PDO-Verbindung schreiben, der protokolliert und eine Ausnahme auslöst, wenn eine Fehlermeldung angezeigt wird.

Hier ist ein einfaches Beispiel:

class LoggedPDOSTatement extends PDOStatement    {

function execute ($array)    {
    parent::execute ($array);
    $errors = parent::errorInfo();
    if ($errors[0] != '00000'):
        throw new Exception ($errors[2]);
    endif;
  }

}

Sie können diese Klasse also anstelle von PDOStatement verwenden:

$this->db->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('LoggedPDOStatement', array()));

Hier eine erwähnte PDO Decorator Implementierung:

class LoggedPDOStatement    {

function __construct ($stmt)    {
    $this->stmt = $stmt;
}

function execute ($params = null)    {
    $result = $this->stmt->execute ($params); 
    if ($this->stmt->errorCode() != PDO::ERR_NONE):
        $errors = $this->stmt->errorInfo();
        $this->paint ($errors[2]);
    endif;
    return $result;
}

function bindValue ($key, $value)    {
    $this->values[$key] = $value;    
    return $this->stmt->bindValue ($key, $value);
}

function paint ($message = false)    {
    echo '<pre>';
    echo '<table cellpadding="5px">';
    echo '<tr><td colspan="2">Message: ' . $message . '</td></tr>';
    echo '<tr><td colspan="2">Query: ' . $this->stmt->queryString . '</td></tr>';
    if (count ($this->values) > 0):
    foreach ($this->values as $key => $value):
    echo '<tr><th align="left" style="background-color: #ccc;">' . $key . '</th><td>' . $value . '</td></tr>';
    endforeach;
    endif;
    echo '</table>';
    echo '</pre>';
}

function __call ($method, $params)    {
    return call_user_func_array (array ($this->stmt, $method), $params); 
}

}
bkilinc
quelle
2

Um MySQL in WAMP zu protokollieren , müssen Sie die Datei my.ini bearbeiten (z. B. unter wamp \ bin \ mysql \ mysql5.6.17 \ my.ini).

und hinzufügen zu [mysqld]:

general_log = 1
general_log_file="c:\\tmp\\mysql.log"
Spezi
quelle
1

Hier ist eine Funktion, die ich gemacht habe, um eine SQL-Abfrage mit "aufgelösten" Parametern zurückzugeben.

function paramToString($query, $parameters) {
    if(!empty($parameters)) {
        foreach($parameters as $key => $value) {
            preg_match('/(\?(?!=))/i', $query, $match, PREG_OFFSET_CAPTURE);
            $query = substr_replace($query, $value, $match[0][1], 1);
        }
    }
    return $query;
    $query = "SELECT email FROM table WHERE id = ? AND username = ?";
    $values = [1, 'Super'];

    echo paramToString($query, $values);

Angenommen, Sie führen so aus

$values = array(1, 'SomeUsername');
$smth->execute($values);

Diese Funktion fügt Abfragen KEINE Anführungszeichen hinzu, erledigt aber die Arbeit für mich.

rezden
quelle
0

Das Problem, das ich mit der Lösung zum Abfangen von PDO-Ausnahmen für Debugging-Zwecke hatte, ist, dass nur PDO-Ausnahmen (duh) abgefangen wurden, aber keine Syntaxfehler abgefangen wurden, die als PHP-Fehler registriert wurden (ich bin nicht sicher, warum dies so ist, aber " warum "ist für die Lösung irrelevant). Alle meine PDO-Aufrufe stammen aus einer einzelnen Tabellenmodellklasse, die ich für alle meine Interaktionen mit allen Tabellen erweitert habe. Dies war kompliziert, als ich versuchte, Code zu debuggen, da der Fehler die Zeile des PHP-Codes registrieren würde, in der sich mein Ausführungsaufruf befand rief an, sagte mir aber nicht, woher der Anruf tatsächlich kam. Ich habe den folgenden Code verwendet, um dieses Problem zu lösen:

/**
 * Executes a line of sql with PDO.
 * 
 * @param string $sql
 * @param array $params
 */
class TableModel{
    var $_db; //PDO connection
    var $_query; //PDO query

    function execute($sql, $params) { 
        //we're saving this as a global, so it's available to the error handler
        global $_tm;
        //setting these so they're available to the error handler as well
        $this->_sql = $sql;
        $this->_paramArray = $params;            

        $this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->_query = $this->_db->prepare($sql);

        try {
            //set a custom error handler for pdo to catch any php errors
            set_error_handler('pdoErrorHandler');

            //save the table model object to make it available to the pdoErrorHandler
            $_tm = $this;
            $this->_query->execute($params);

            //now we restore the normal error handler
            restore_error_handler();
        } catch (Exception $ex) {
            pdoErrorHandler();
            return false;
        }            
    }
}

Der obige Code fängt also sowohl PDO-Ausnahmen als auch PHP-Syntaxfehler ab und behandelt sie auf die gleiche Weise. Mein Fehlerbehandler sieht ungefähr so ​​aus:

function pdoErrorHandler() {
    //get all the stuff that we set in the table model
    global $_tm;
    $sql = $_tm->_sql;
    $params = $_tm->_params;
    $query = $tm->_query;

    $message = 'PDO error: ' . $sql . ' (' . implode(', ', $params) . ") \n";

    //get trace info, so we can know where the sql call originated from
    ob_start();
    debug_backtrace(); //I have a custom method here that parses debug backtrace, but this will work as well
    $trace = ob_get_clean();

    //log the error in a civilized manner
    error_log($message);

    if(admin(){
        //print error to screen based on your environment, logged in credentials, etc.
        print_r($message);
    }
}

Wenn jemand bessere Ideen hat, wie er relevante Informationen an meinen Fehlerbehandler weiterleiten kann, als das Tabellenmodell als globale Variable festzulegen, würde ich mich freuen, es zu hören und meinen Code zu bearbeiten.

Troy Knapp
quelle
0

Dieser Code funktioniert gut für mich:

echo str_replace(array_keys($data), array_values($data), $query->queryString);

Vergessen Sie nicht, $ data und $ query durch Ihre Namen zu ersetzen

user3553866
quelle
0

Ich benutze diese Klasse, um PDO zu debuggen (mit Log4PHP )

<?php

/**
 * Extends PDO and logs all queries that are executed and how long
 * they take, including queries issued via prepared statements
 */
class LoggedPDO extends PDO
{

    public static $log = array();

    public function __construct($dsn, $username = null, $password = null, $options = null)
    {
        parent::__construct($dsn, $username, $password, $options);
    }

    public function query($query)
    {
        $result = parent::query($query);
        return $result;
    }

    /**
     * @return LoggedPDOStatement
     */
    public function prepare($statement, $options = NULL)
    {
        if (!$options) {
            $options = array();
        }
        return new \LoggedPDOStatement(parent::prepare($statement, $options));
    }
}

/**
 * PDOStatement decorator that logs when a PDOStatement is
 * executed, and the time it took to run
 * @see LoggedPDO
 */
class LoggedPDOStatement
{

    /**
     * The PDOStatement we decorate
     */
    private $statement;
    protected $_debugValues = null;

    public function __construct(PDOStatement $statement)
    {
        $this->statement = $statement;
    }

    public function getLogger()
    {
        return \Logger::getLogger('PDO sql');
    }

    /**
     * When execute is called record the time it takes and
     * then log the query
     * @return PDO result set
     */
    public function execute(array $params = array())
    {
        $start = microtime(true);
        if (empty($params)) {
            $result = $this->statement->execute();
        } else {
            foreach ($params as $key => $value) {
                $this->_debugValues[$key] = $value;
            }
            $result = $this->statement->execute($params);
        }

        $this->getLogger()->debug($this->_debugQuery());

        $time = microtime(true) - $start;
        $ar = (int) $this->statement->rowCount();
        $this->getLogger()->debug('Affected rows: ' . $ar . ' Query took: ' . round($time * 1000, 3) . ' ms');
        return $result;
    }

    public function bindValue($parameter, $value, $data_type = false)
    {
        $this->_debugValues[$parameter] = $value;
        return $this->statement->bindValue($parameter, $value, $data_type);
    }

    public function _debugQuery($replaced = true)
    {
        $q = $this->statement->queryString;

        if (!$replaced) {
            return $q;
        }

        return preg_replace_callback('/:([0-9a-z_]+)/i', array($this, '_debugReplace'), $q);
    }

    protected function _debugReplace($m)
    {
        $v = $this->_debugValues[$m[0]];

        if ($v === null) {
            return "NULL";
        }
        if (!is_numeric($v)) {
            $v = str_replace("'", "''", $v);
        }

        return "'" . $v . "'";
    }

    /**
     * Other than execute pass all other calls to the PDOStatement object
     * @param string $function_name
     * @param array $parameters arguments
     */
    public function __call($function_name, $parameters)
    {
        return call_user_func_array(array($this->statement, $function_name), $parameters);
    }
}
Janos Szabo
quelle
0

Genau dafür habe ich hier ein modernes Composer-geladenes Projekt / Repository erstellt:

pdo-debug

Hier finden Sie das GitHub-Zuhause des Projekts. Ein Blog-Beitrag erklärt es hier . Eine Zeile, die Sie in Ihre composer.json einfügen müssen, und dann können Sie sie folgendermaßen verwenden:

echo debugPDO($sql, $parameters);

$ sql ist die unformatierte SQL-Anweisung, $ parameters ist ein Array Ihrer Parameter: Der Schlüssel ist der Platzhaltername (": user_id") oder die Nummer des unbenannten Parameters ("?"), der Wert ist .. na ja, der Wert.

Die Logik dahinter: Dieses Skript bewertet die Parameter einfach und ersetzt sie durch die bereitgestellte SQL-Zeichenfolge. Super einfach, aber für 99% Ihrer Anwendungsfälle sehr effektiv. Hinweis: Dies ist nur eine grundlegende Emulation, kein echtes PDO-Debugging (da dies nicht möglich ist, da PHP getrenntes SQL und Parameter an den MySQL-Server sendet).

Ein großes Dankeschön an bigwebguy und Mike vom StackOverflow-Thread Abrufen einer rohen SQL- Abfragezeichenfolge von PDO für das Schreiben der gesamten Hauptfunktion hinter diesem Skript. Groß auf!

Sliq
quelle
0

So debuggen Sie PDO-MySQL-Datenbankabfragen in Ubuntu

TL; DR Protokollieren Sie alle Ihre Abfragen und beenden Sie das MySQL-Protokoll.

Diese Anweisungen gelten für meine Installation von Ubuntu 14.04. Geben Sie den Befehl ein lsb_release -a, um Ihre Version abzurufen. Ihre Installation kann anders sein.

Aktivieren Sie die Anmeldung in MySQL

  1. Gehen Sie zu Ihrer Dev Server Cmd Zeile
  2. Verzeichnisse ändern cd /etc/mysql. Sie sollten eine Datei mit dem Namen sehen my.cnf. Das ist die Datei, die wir ändern werden.
  3. Stellen Sie sicher, dass Sie am richtigen Ort sind, indem Sie eingeben cat my.cnf | grep general_log. Dadurch wird die my.cnfDatei für Sie gefiltert . Sie sollten zwei Einträge sehen: #general_log_file = /var/log/mysql/mysql.log&& #general_log = 1.
  4. Kommentieren Sie diese beiden Zeilen aus und speichern Sie sie über den Editor Ihrer Wahl.
  5. Starten Sie mysql neu : sudo service mysql restart.
  6. Möglicherweise müssen Sie auch Ihren Webserver neu starten. (Ich kann mich nicht an die Sequenz erinnern, die ich verwendet habe). Für meine Installation ist das nginx : sudo service nginx restart.

Gute Arbeit! Du bist fertig. Jetzt müssen Sie nur noch die Protokolldatei abschließen, damit Sie die PDO-Abfragen Ihrer App in Echtzeit sehen können.

Beenden Sie das Protokoll, um Ihre Abfragen anzuzeigen

Geben Sie dieses cmd ein tail -f /var/log/mysql/mysql.log.

Ihre Ausgabe sieht ungefähr so ​​aus:

73 Connect  xyz@localhost on your_db
73 Query    SET NAMES utf8mb4
74 Connect  xyz@localhost on your_db
75 Connect  xyz@localhost on your_db
74 Quit 
75 Prepare  SELECT email FROM customer WHERE email=? LIMIT ?
75 Execute  SELECT email FROM customer WHERE email='[email protected]' LIMIT 5
75 Close stmt   
75 Quit 
73 Quit 

Alle neuen Abfragen, die Ihre App stellt, werden automatisch angezeigt, solange Sie das Protokoll weiter verfolgen. Um den Schwanz zu verlassen, drücken Sie cmd/ctrl c.

Anmerkungen

  1. Achtung: Diese Protokolldatei kann sehr groß werden. Ich führe dies nur auf meinem Entwicklungsserver aus.
  2. Protokolldatei wird zu groß? Schneiden Sie es ab. Das heißt, die Datei bleibt, aber der Inhalt wird gelöscht. truncate --size 0 mysql.log.
  3. Cool, dass die Protokolldatei die MySQL-Verbindungen auflistet. Ich weiß, dass einer davon aus meinem alten MySQL-Code stammt, von dem ich übergehe. Der dritte stammt von meiner neuen PDO-Verbindung. Ich bin mir jedoch nicht sicher, woher der zweite kommt. Wenn Sie einen schnellen Weg kennen, lassen Sie es mich wissen.

Kredit & danke

Ein großes Dankeschön an Nathan Longs Antwort oben, damit die Inspo dies auf Ubuntu herausfinden kann. Auch an Dikirill für seinen Kommentar zu Nathans Beitrag, der mich zu dieser Lösung führte.

Ich liebe dich Stackoverflow!

Ellenbogenlobstercowstand
quelle
0

In der Debian NGINX-Umgebung habe ich Folgendes getan.

Gehen Sie zur /etc/mysql/mysql.conf.dBearbeitung, mysqld.cnfwenn Sie log-error = /var/log/mysql/error.logdie folgenden 2 Zeilen darunter finden.

general_log_file        = /var/log/mysql/mysql.log
general_log             = 1

Um die Protokolle zu sehen, gehe zu /var/log/mysqlund tail -f mysql.log

Denken Sie daran, diese Zeilen zu kommentieren, wenn Sie mit dem Debuggen fertig sind, wenn Sie sich in einer Produktionsumgebung befinden. Löschen Sie mysql.logdiese, da diese Protokolldatei schnell wächst und sehr groß sein kann.

Khan
quelle
Nicht jeder benutzt MySQL.
Gefürchtetes Semikolon