Masalah yang saya miliki dengan solusi untuk menangkap pengecualian PDO untuk tujuan debug adalah bahwa ia hanya menangkap pengecualian PDO (duh), tetapi tidak menangkap kesalahan sintaks yang terdaftar sebagai kesalahan php (saya tidak yakin mengapa ini, tapi " mengapa "tidak relevan dengan solusi). Semua panggilan PDO saya berasal dari kelas model tabel tunggal yang saya perpanjang untuk semua interaksi saya dengan semua tabel ... ini hal yang rumit ketika saya mencoba untuk men-debug kode, karena kesalahan akan mendaftarkan baris kode php di mana panggilan eksekusi saya menelepon, tetapi tidak memberi tahu saya dari mana panggilan itu, sebenarnya, dibuat. Saya menggunakan kode berikut untuk mengatasi masalah ini:
/**
* 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;
}
}
}
Jadi, kode di atas menangkap KEDUA PDO pengecualian DAN kesalahan sintaks php dan memperlakukan mereka dengan cara yang sama. Penangan kesalahan saya terlihat seperti ini:
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);
}
}
Jika ada yang punya ide yang lebih baik tentang cara mendapatkan info yang relevan untuk penangan kesalahan saya daripada menetapkan model tabel sebagai variabel global, saya akan senang mendengarnya dan mengedit kode saya.
/var/log/mysql/*
. Parameter terikat PDO tidak dapat menyebabkan kesalahan sintaks sehingga yang Anda butuhkan adalah kueri SQL yang disiapkan.