Vấn đề tôi gặp phải với giải pháp bắt các miễn trừ PDO cho mục đích gỡ lỗi là nó chỉ bắt được các miễn trừ PDO (duh), nhưng không bắt được các lỗi cú pháp đã được đăng ký là lỗi php (Tôi không chắc tại sao lại như vậy, nhưng " tại sao "không liên quan đến giải pháp). Tất cả các cuộc gọi PDO của tôi đến từ một lớp mô hình bảng duy nhất mà tôi đã mở rộng cho tất cả các tương tác của mình với tất cả các bảng ... điều này phức tạp khi tôi đang cố gắng gỡ lỗi mã, vì lỗi sẽ đăng ký dòng mã php nơi cuộc gọi thực thi của tôi là được gọi, nhưng không cho tôi biết cuộc gọi thực sự được thực hiện từ đâu. Tôi đã sử dụng đoạn mã sau để giải quyết vấn đề này:
/**
* 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;
}
}
}
Vì vậy, đoạn mã trên bắt được các ngoại lệ BÓNG PDO VÀ lỗi cú pháp php và xử lý chúng theo cùng một cách. Trình xử lý lỗi của tôi trông giống như thế này:
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);
}
}
Nếu bất cứ ai có ý tưởng tốt hơn về cách nhận thông tin liên quan đến trình xử lý lỗi của tôi hơn là đặt mô hình bảng làm biến toàn cục, tôi sẽ rất vui khi nghe và chỉnh sửa mã của mình.
/var/log/mysql/*
. Các tham số ràng buộc PDO không thể gây ra lỗi cú pháp, vì vậy tất cả những gì bạn cần là truy vấn SQL đã chuẩn bị.