Проблема, з якою у мене виникло рішення щодо вилучення PDO-винятків для цілей налагодження, полягає в тому, що він зафіксував виключення виключень PDO (duh), але не вловив синтаксичні помилки, які були зареєстровані як помилки php (я не впевнений, чому це так, але " чому "не має значення для рішення). Всі мої дзвінки в PDO походять з одного модельного класу таблиці, який я розширив для всіх моїх взаємодій зі всіма таблицями ... це складні речі, коли я намагався налагодити код, оскільки помилка зареєструвала рядок 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;
}
}
}
Отже, наведений вище код виявляє BOTH 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-запит.