Php CodeIgniter-如何捕获数据库错误?

Php CodeIgniter-如何捕获数据库错误?,php,codeigniter,Php,Codeigniter,有没有办法让CI在遇到DB错误时引发异常,而不是显示如下消息: 发生数据库错误,错误号:1054 “where子句”中的未知列“foo”从(FooBar)中选择*,其中foo=“1” 注意:我只希望在一个控制器中发生这种情况。在其他控制器中,我很高兴它能显示DB错误消息。试试这些CI函数 $this->db->_error_message(); (mysql_error equivalent) $this->db->_error_number(); (mysql_errn

有没有办法让CI在遇到DB错误时引发异常,而不是显示如下消息:

发生数据库错误,错误号:1054 “where子句”中的未知列“foo”从(
FooBar
)中选择*,其中
foo
=“1”

注意:我只希望在一个控制器中发生这种情况。在其他控制器中,我很高兴它能显示DB错误消息。

试试这些CI函数

$this->db->_error_message(); (mysql_error equivalent)
$this->db->_error_number(); (mysql_errno equivalent)
CODEIGNITER 3的更新

函数已弃用,请改用
error()

$this->db->error(); 
也许是这样:

$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;

您将在配置文件夹的database.php中更改它。我知道此线程很旧,但只是为了防止其他人有此问题。这是我在不涉及CI db类的情况下使用的技巧。将调试保持打开状态,并在错误视图文件中引发异常

因此,在db配置中,您有:

$db['default']['db_debug'] = true;
然后在数据库错误视图文件中,我的文件位于
application/errors/error\u 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()方法将返回一个包含其代码和消息的数组


将此代码放在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
{

}

我为此创建了一个简单的库:

<?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
            )
        );
    }

}
我可以在我的控制器中这样捕捉它:

 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);
    }

}

而当查询被自动创建时,
$this->db->last\u query()
也很有用。这些如何防止消息显示?您必须在config/database.php->$db['default']['db\u debug']=FALSE中关闭数据库的调试;为什么不能改为使用异常:-(?这些方法在CodeIgniter版本3中已被删除。请改为使用
$this->db->error()
。(请参阅)Thx!他们在他们的CI 2->3迁移指南中没有提到这一点!太好了,你救了我一天..我在CI 2Codeigniter停止代码执行并在出现错误时输出错误消息,因此你将没有机会检查$this->db->error。这个答案不正确。@S.Imp-CodeIgniter仅在config/dat时停止执行abase.php的
$db['default']['db_debug']
是正确的。请参阅。您是否生活在并行世界中?这在使用pdo驱动程序进行psql@RayJ知道为什么db_调试“生产”环境默认值(
“db_调试”=>(环境!==“生产”
)吗在新下载的CI v3中是否设置为FALSE?我看到将其设置为FALSE将显示db error的更多详细信息,这在生产中是不可能的,对吗?我感到困惑。首先,我们需要返回到主index.php文件,看看环境是如何设置的以及为什么设置的。众所周知,这可以设置为:define('ENVIRONMENT','development')):在开发时显示错误。define('ENVIRONMENT','production'):当站点处于活动状态时。因此(在database.php配置中)行显示:'db_debug'=>(ENVIRONMENT!='production'),或者如果“ENVIRONMENT”未设置为“production”,则将数据库调试模式设置为TRUE。请用英语回答,因为这是一个英语网站!
/**
 * 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.