CodeIgniter-如何捕捉数据库错误?

有没有办法让 线人在遇到 数据库错误时抛出一个 例外,而不是显示如下信息:

发生的数据库错误错误号: 1054 ‘ WHERE 子句’SELECT * FROM (FooBar) WHERE foo =’1’中的未知列‘ foo’

注意: 我只希望这在一个控制器中发生。在其他控制器中,我很高兴它显示 数据库错误消息

232777 次浏览

使用 error()方法:

$this->db->error();

对于 CodeIgniter 2,可以使用下列现在已不推荐使用的函数:

$this->db->_error_message(); (mysql_error equivalent)
$this->db->_error_number(); (mysql_errno equivalent)

也许是这样:

$db_debug = $this->db->db_debug; //save setting


$this->db->db_debug = FALSE; //disable debugging for queries


$result = $this->db->query($sql); //run query


//check for errors, etc


$this->db->db_debug = $db_debug; //restore setting

必须在 config/database. php-> 中关闭数据库的调试

$db['default']['db_debug'] = FALSE;

这对你的网站安全更好。

好好利用

    $this->db->_error_message();

这是更好的发现错误。在完成您的网站。 关闭错误消息 使用它

    $db['default']['db_debug'] = FALSE;

您将在您的配置文件夹的 datase.php 中更改它

我知道这个帖子有些年头了,但是以防万一还有其他人也有这个问题。这是我在没有触及 CI db 类的情况下使用的一个技巧。在错误视图文件中保留调试,并引发异常。

所以在你的 db 配置中,你有:

$db['default']['db_debug'] = true;

然后在数据库错误视图文件中,我的文件在 application/errors/error_db.php中用以下内容替换所有内容:

<?php
$message = preg_replace('/(<\/?p>)+/', ' ', $message);
throw new Exception("Database error occured with message : {$message}");


?>

因为将调用视图文件,所以总是会抛出异常,您可以稍后为不同的环境添加不同的视图。

在 Codeigniter 3.0(CI3)中,您所要做的就是 $this->db->error()

如果您需要获取上一次发生的错误,error ()方法将返回一个包含其代码和消息的数组

Http://www.codeigniter.com/user_guide/database/queries.html#handling-errors

将这段代码放在 application/core 文件夹中的 MY _ Exceptions.php 文件中:

<?php


if (!defined('BASEPATH'))
exit('No direct script access allowed');


/**
* Class dealing with errors as exceptions
*/
class MY_Exceptions extends CI_Exceptions
{


/**
* Force exception throwing on erros
*/
public function show_error($heading, $message, $template = 'error_general', $status_code = 500)
{
set_status_header($status_code);


$message = implode(" / ", (!is_array($message)) ? array($message) : $message);


throw new CiError($message);
}


}


/**
* Captured error from Code Igniter
*/
class CiError extends Exception
{


}

它将使所有代码点火器错误作为 Exception (CiError)处理。然后,打开所有数据库调试:

$db['default']['db_debug'] = true;

我为此创建了一个简单的图书馆:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');


class exceptions {


public function checkForError() {
get_instance()->load->database();
$error = get_instance()->db->error();
if ($error['code'])
throw new MySQLException($error);
}
}


abstract class UserException extends Exception {
public abstract function getUserMessage();
}


class MySQLException extends UserException {
private $errorNumber;
private $errorMessage;


public function __construct(array $error) {
$this->errorNumber = "Error Code(" . $error['code'] . ")";
$this->errorMessage = $error['message'];
}


public function getUserMessage() {
return array(
"error" => array (
"code" => $this->errorNumber,
"message" => $this->errorMessage
)
);
}


}

示例查询:

function insertId($id){
$data = array(
'id' => $id,
);


$this->db->insert('test', $data);
$this->exceptions->checkForError();
return $this->db->insert_id();
}

我可以通过我的控制器捕捉到它:

 try {
$this->insertThings->insertId("1");
} catch (UserException $error){
//do whatever you want when there is an mysql error


}

如果使用 PDO,除了上述所有答案之外。

如下所示,我默默地记录我的错误

        $q = $this->db->conn_id->prepare($query);


if($q instanceof PDOStatement) {
// go on with bind values and execute


} else {


$dbError = $this->db->error();
$this->Logger_model->logError('Db Error', date('Y-m-d H:i:s'), __METHOD__.' Line '.__LINE__, 'Code: '.$dbError['code'].' -  '.'Message: '.$dbError['message']);


}

禁用错误调试。

    $data_user = $this->getDataUser();
$id_user   = $this->getId_user();


$this->db->db_debug = false;
$this->db->where(['id' => $id_user]);
$res = $this->db->update(self::$table, $data_user['user']);


if(!$res)
{
$error = $this->db->error();
return $error;
//return array $error['code'] & $error['message']
}
else
{
return 1;
}

这个例子对我很有用:

$query = "some buggy sql statement";


$this->db->db_debug = false;


if(!@$this->db->query($query))
{
$error = $this->db->error();
// do something in error case
}else{
// do something in success case
}
...

在 sybase _ Driver. php 中

/**
* Manejador de Mensajes de Error Sybase
* Autor: Isaí Moreno
* Fecha: 06/Nov/2019
*/


static  $CODE_ERROR_SYBASE;


public static function SetCodeErrorSybase($Code) {
if ($Code != 3621) {  /*No se toma en cuenta el código de command aborted*/
CI_DB_sybase_driver::$CODE_ERROR_SYBASE = trim(CI_DB_sybase_driver::$CODE_ERROR_SYBASE.' '.$Code);
}
}


public static function GetCodeErrorSybase() {
return CI_DB_sybase_driver::$CODE_ERROR_SYBASE;
}


public static function msg_handler($msgnumber, $severity, $state, $line, $text)
{
log_message('info', 'CI_DB_sybase_driver - CODE ERROR ['.$msgnumber.'] Mensaje - '.$text);
CI_DB_sybase_driver::SetCodeErrorSybase($msgnumber);
}


// ------------------------------------------------------------------------

在同一个 sybase _ driver.php 文件中添加和修改以下方法

/**
* The error message number
*
* @access  private
* @return  integer
*/
function _error_number()
{
// Are error numbers supported?
return CI_DB_sybase_driver::GetCodeErrorSybase();
}


function _sybase_set_message_handler()
{
// Are error numbers supported?
return sybase_set_message_handler('CI_DB_sybase_driver::msg_handler');
}

实现控制器的功能。

public function Eliminar_DUPLA(){
if($this->session->userdata($this->config->item('mycfg_session_object_name'))){
//***/
$Operacion_Borrado_Exitosa=false;
$this->db->trans_begin();


$this->db->_sybase_set_message_handler();  <<<<<------- Activar Manejador de errores de sybase
$Dupla_Eliminada=$this->Mi_Modelo->QUERY_Eliminar_Dupla($PARAMETROS);


if ($Dupla_Eliminada){
$this->db->trans_commit();
MostrarNotificacion("Se eliminó DUPLA exitosamente","OK",true);
$Operacion_Borrado_Exitosa=true;
}else{
$Error = $this->db->_error_number();  <<<<----- Obtengo el código de error de sybase para personilzar mensaje al usuario
$this->db->trans_rollback();
MostrarNotificacion("Ocurrio un error al intentar eliminar Dupla","Error",true);
if ($Error == 547) {
MostrarNotificacion("<strong>Código de error :[".$Error.']. No se puede eliminar documento Padre.</strong>',"Error",true);
}  else {
MostrarNotificacion("<strong>Código de Error :[".$Error.']</strong><br>',"Error",true);
}
}


echo "@".Obtener_Contador_Notificaciones();
if ($Operacion_Borrado_Exitosa){
echo "@T";
}else{
echo "@F";
}
}else{
redirect($this->router->default_controller);
}


}

在日志中,您可以检查数据库服务器发送的代码和消息。

INFO - 2019-11-06 19:26:33 -> CI_DB_sybase_driver - CODE ERROR [547] Message - Dependent foreign key constraint violation in a referential integrity constraint. dbname = 'database', table name = 'mitabla', constraint name = 'FK_SR_RELAC_REFERENCE_SR_mitabla'. INFO - 2019-11-06 19:26:33 -> CI_DB_sybase_driver - CODE ERROR [3621] Message - Command has been aborted. ERROR - 2019-11-06 19:26:33 -> Query error: - Invalid query: delete from mitabla where ID = 1019.