Проблема, с которой я столкнулся с решением перехватить исключения PDO для целей отладки, заключается в том, что он перехватывал только исключения PDO (duh), но не распознавал синтаксические ошибки, которые были зарегистрированы как ошибки php (я не уверен, почему , но «почему» не имеет отношения к решению). Все мои вызовы PDO исходят из одного класса модели таблицы, который я расширил для всех моих взаимодействий со всеми таблицами ... это было сложно, когда я пытался отладить код, потому что ошибка регистрировала строку кода php, где был мой вызов execute позвонил, но не сказал мне, откуда был сделан звонок. Я использовал следующий код для решения этой проблемы:
/**
* 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;
}
}
}
Итак, приведенный выше код перехватывает ОБА исключения PDO и синтаксические ошибки php и обрабатывает их одинаково. Мой обработчик ошибок выглядит примерно так:
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);
}
}
Если у кого-то есть идеи о том, как получить релевантную информацию для моего обработчика ошибок, чем указание модели таблицы в качестве глобальной переменной, я был бы рад услышать ее и отредактировать свой код.