我为调试目的而捕获PDO豁免的解决方案的问题在于,它仅捕获了PDO豁免(duh),却没有捕获被注册为php错误的语法错误(我不确定为什么会这样,但是“为什么”与解决方案无关。我所有的PDO调用都来自一个表模型类,我将其扩展为与所有表的所有交互...在尝试调试代码时,这很复杂,因为错误会在我的execute调用所在的位置注册php代码行打电话了,但没有告诉我实际上是从哪里打来的电话。我使用以下代码来解决此问题:
/**
* 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);
}
}
如果有人比将表模型设置为全局变量更好地了解与错误处理程序相关的信息,我将很高兴听到并编辑我的代码。
/var/log/mysql/*
。PDO绑定的参数不会导致语法错误,因此您所需要做的只是准备好的SQL查询。