Le problème que j'ai eu avec la solution pour attraper les exemptions PDO à des fins de débogage est qu'elle n'a attrapé que les exemptions PDO (duh), mais n'a pas attrapé les erreurs de syntaxe qui ont été enregistrées comme des erreurs php (je ne sais pas pourquoi, mais " pourquoi "est sans rapport avec la solution). Tous mes appels PDO proviennent d'une seule classe de modèle de table que j'ai étendue pour toutes mes interactions avec toutes les tables ... cela compliquait les choses lorsque j'essayais de déboguer du code, car l'erreur enregistrerait la ligne de code php où mon appel d'exécution était appelé, mais ne m'a pas dit d'où l'appel était en fait. J'ai utilisé le code suivant pour résoudre ce problème:
/**
* 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;
}
}
}
Ainsi, le code ci-dessus détecte À LA FOIS les exceptions PDO ET les erreurs de syntaxe php et les traite de la même manière. Mon gestionnaire d'erreurs ressemble à ceci:
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 quelqu'un a de meilleures idées sur la façon d'obtenir des informations pertinentes pour mon gestionnaire d'erreurs que de définir le modèle de table en tant que variable globale, je serais heureux de l'entendre et de modifier mon code.
/var/log/mysql/*
. Les paramètres liés à PDO ne peuvent pas provoquer d'erreurs de syntaxe, il vous suffit donc de la requête SQL préparée.