El problema que tuve con la solución para capturar exenciones de PDO para propósitos de depuración es que solo capturó exenciones de PDO (duh), pero no detectó errores de sintaxis que se registraron como errores de php (no estoy seguro de por qué esto es así, pero " por qué "es irrelevante para la solución). Todas mis llamadas PDO provienen de una clase de modelo de tabla única que extendí para todas mis interacciones con todas las tablas ... esto complicaba las cosas cuando intentaba depurar código, porque el error registraba la línea de código php donde estaba mi llamada de ejecución llamé, pero no me dijo de dónde se estaba haciendo la llamada. Usé el siguiente código para resolver este 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;
}
}
}
Entonces, el código anterior detecta AMBAS excepciones PDO Y errores de sintaxis php y los trata de la misma manera. Mi controlador de errores se parece a esto:
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);
}
}
Si alguien tiene mejores ideas sobre cómo obtener información relevante para mi controlador de errores que configurar el modelo de tabla como una variable global, me complacería escucharlo y editar mi código.
/var/log/mysql/*
. Los parámetros vinculados a PDO no pueden causar errores de sintaxis, por lo que todo lo que necesita es la consulta SQL preparada.