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.
/var/log/mysql/*
. PDO-gebundene Parameter können keine Syntaxfehler verursachen. Sie benötigen daher nur die vorbereitete SQL-Abfrage.