Il problema che ho avuto con la soluzione per catturare le esenzioni DOP a scopo di debug è che ha rilevato solo esenzioni DOP (duh), ma non ha rilevato errori di sintassi registrati come errori php (non sono sicuro del perché, ma " perché "è irrilevante per la soluzione). Tutte le mie chiamate PDO provengono da una singola classe del modello di tabella che ho esteso per tutte le mie interazioni con tutte le tabelle ... questo complicato cose quando stavo cercando di eseguire il debug del codice, perché l'errore avrebbe registrato la riga di codice php in cui era la mia chiamata di esecuzione ha chiamato, ma non mi ha detto da dove proveniva la chiamata. Ho usato il seguente codice per risolvere questo problema:
/**
* 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;
}
}
}
Quindi, il codice sopra coglie ENTRAMBE le eccezioni DOP E gli errori di sintassi php e le tratta allo stesso modo. Il mio gestore degli errori è simile al seguente:
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);
}
}
Se qualcuno ha idee migliori su come ottenere informazioni rilevanti per il mio gestore errori rispetto all'impostazione del modello di tabella come variabile globale, sarei felice di ascoltarlo e modificare il mio codice.
/var/log/mysql/*
. I parametri associati PDO non possono causare errori di sintassi, quindi è sufficiente la query SQL preparata.