CodeIgniter:Try Catch 在模型类中不起作用 [英] CodeIgniter: Try Catch is not working in model class

查看:41
本文介绍了CodeIgniter:Try Catch 在模型类中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对列有一个 unique 约束.当此代码运行时,我从框架中获取错误日志,但这不是我在异常块中给出的.
如果存在唯一列,那么我想查询其主键并将其设置为 $id 并返回页面.现在它因数据库错误而停止,并且不会进入 Catch 块.
这是我的代码:

尝试{$result = $this->db->insert('email', $new_email);如果($结果){$id = $this->db->insert_id();} 别的 {throw new Exception("$$$$$$$$$$$$日志数据库错误");}} 捕获(异常 $e){log_message('error',$e->getMessage());返回;}

**Error Messages** 我从框架中得到:

DEBUG - 2013-04-07 05:00:38 -->数据库事务失败错误 - 2013-04-07 05:00:38 -->查询错误:重复条目

我不知道它有什么问题.

解决方案

CI 对异常没有很好的支持.您的数据库查询会调用一些模糊的 CI error_logging 东西,称为 show_error().您需要做的是设置适当的异常处理.

基本上你可以遵循整个食谱.

现在你所有的数据库错误都会自动抛出异常.作为奖励,您可以在整个 CI 应用程序中进行良好的异常处理.

注册一个自定义错误处理程序,将 PHP 错误转换为异常,例如将其放在 config/config.php 的顶部

function my_error_handler($errno, $errstr, $errfile, $errline){如果 (!(error_reporting() & $errno)){//此错误代码不包含在 error_reporting 中返回;}log_message('error', "$errstr @$errfile::$errline($errno)");throw new ErrorException( $errstr, $errno, 0, $errfile, $errline );}set_error_handler("my_error_handler");

注册一个未捕获的异常处理程序,在你的 config/config.php 中放入类似的内容

function my_exception_handler($exception){echo '

';打印_r($异常);echo '</pre>';header("HTTP/1.0 500 内部服务器错误");}set_exception_handler("my_exception_handler");

设置终止处理程序:

function my_fatal_handler(){$errfile = "未知文件";$errstr = "致命错误";$errno = E_CORE_ERROR;$错误线= 0;$error = error_get_last();如果 ( $error !== NULL ){echo '

';打印_r($错误);echo '</pre>';header("HTTP/1.0 500 内部服务器错误");}}register_shutdown_function("my_fatal_handler");

设置一个自定义断言处理程序,将断言转换为异常,在您的 config/config.php 中放入类似内容:

function my_assert_handler($file, $line, $code){log_message('debug', "断言失败@$file::$line($code)");throw new Exception("断言失败@$file::$line($code)");}断言选项(ASSERT_ACTIVE,1);assert_options(ASSERT_WARNING, 0);断言选项(ASSERT_BAIL,0);断言选项(ASSERT_QUIET_EVAL,0);assert_options(ASSERT_CALLBACK, 'my_assert_handler');

在控制器中使用这样的包装器

公共函数controller_method(){尝试{//正常流量}捕获(异常 $e){log_message( 'error', $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine() );//出错时}}

您可以根据自己的喜好调整和自定义整个内容!

希望这会有所帮助.

您还需要拦截 CI show_error 方法.把它放在 application/core/MY_exceptions.php:

class MY_Exceptions 扩展 CI_Exceptions{函数 show_error($heading, $message, $template = 'error_general', $status_code = 500){log_message('debug', print_r($message, TRUE));throw new Exception(is_array($message) ? $message[1] : $message, $status_code );}}

并在 application/config/database.php 中将此设置保留为 FALSE,以便将数据库错误转换为异常.

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

CI 有一些(非常)弱点,例如异常处理,但这将大有帮助.

如果您打算使用事务,请确保对异常进行回滚.与此相关的 NEVER(如在 EVER 中)使用持久连接作为打开的事务和其他会话特定的 DB 状态将被其他会话拾取/继续.

I have a unique constraint on of the column. When this code runs, I get error log from framework but it is not what I have given in Exception block.
If unique column exists then I want to query its primary key and set it as $id and return to the page. Right now it is stopping on db error and not going into Catch block.
Here is my code:

try {
            $result = $this->db->insert('email', $new_email);
            if ($result)
            {
                $id = $this->db->insert_id();    
            } else {
                throw new Exception("$$$$$$$$$$$$$Log database error");
            }
        } catch (Exception $e) {
            log_message('error',$e->getMessage());
            return;
        }

**Error Messages** I get from framework:

DEBUG - 2013-04-07 05:00:38 --> DB Transaction Failure
ERROR - 2013-04-07 05:00:38 --> Query error: Duplicate entry 

I don't know what is wrong with it.

解决方案

CI has no good support for exceptions. You DB queries will call some vague CI error_logging thingie called show_error(). What you need to do is setup proper exception handling.

Basically you can follow the entire recipe.

Now all your database errors will automatically throw exceptions. And as a bonus you have good exception handling in your entire CI application.

Register a custom errorhandler that transforms PHP errors into exceptions, for instance put this in top of your config/config.php

function my_error_handler($errno, $errstr, $errfile, $errline)
{
    if (!(error_reporting() & $errno))
    {
        // This error code is not included in error_reporting
        return;
    }
    log_message('error', "$errstr @$errfile::$errline($errno)" );
    throw new ErrorException( $errstr, $errno, 0, $errfile, $errline );
}
set_error_handler("my_error_handler");

Register an uncaught exception handler, put something like this in your config/config.php

function my_exception_handler($exception)
{
    echo '<pre>';
    print_r($exception);
    echo '</pre>';
    header( "HTTP/1.0 500 Internal Server Error" );
}
set_exception_handler("my_exception_handler");

Set a termination handler:

function my_fatal_handler()
{
    $errfile = "unknown file";
    $errstr  = "Fatal error";
    $errno   = E_CORE_ERROR;
    $errline = 0;
    $error = error_get_last();
    if ( $error !== NULL )
    {
        echo '<pre>';
        print_r($error);
        echo '</pre>';
        header( "HTTP/1.0 500 Internal Server Error" );
    }
}
register_shutdown_function("my_fatal_handler");

Set a custom assert handler that converts asserts into exceptions, put something like this in your config/config.php:

function my_assert_handler($file, $line, $code)
{
    log_message('debug', "assertion failed @$file::$line($code)" );
    throw new Exception( "assertion failed @$file::$line($code)" );
}
assert_options(ASSERT_ACTIVE,     1);
assert_options(ASSERT_WARNING,    0);
assert_options(ASSERT_BAIL,       0);
assert_options(ASSERT_QUIET_EVAL, 0);
assert_options(ASSERT_CALLBACK, 'my_assert_handler');

Use wrappers like this in your controllers

public function controller_method( )
{
    try
    {
        // normal flow
    }
    catch( Exception $e )
    {
        log_message( 'error', $e->getMessage( ) . ' in ' . $e->getFile() . ':' . $e->getLine() );
        // on error
    }
}

You can tune and customize the whole thing to your likings!

Hope this helps.

You will also need to intercept the CI show_error method. Place this in application/core/MY_exceptions.php:

class MY_Exceptions extends CI_Exceptions
{
    function show_error($heading, $message, $template = 'error_general', $status_code = 500)
    {
        log_message( 'debug', print_r( $message, TRUE ) );
        throw new Exception(is_array($message) ? $message[1] : $message, $status_code );
    }
}

And leave in application/config/database.php this setting on FALSE to have database errors converted into exceptions.

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

CI has a few (very) weak points, such as exception-handling but this will go a long way correcting that.

If you are going to use transactions, make sure you do rollbacks on exceptions. Related to this NEVER (as in EVER) use persistant connections as open transactions and other session specific DB state will be picked up / continued by other sessions.

这篇关于CodeIgniter:Try Catch 在模型类中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆