CI 对异常没有很好的支持。您的数据库查询将调用一些模糊的 CI error_logging 事物,称为 show_error()。您需要做的是设置适当的异常处理。
基本上你可以按照整个食谱。
现在你所有的数据库错误都会自动抛出异常。作为奖励,您可以在整个 CI 应用程序中进行良好的异常处理。
注册一个自定义错误处理程序,将 PHP 错误转换为异常,例如将其放在 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");
注册一个未捕获的异常处理程序,在你的 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");
设置终止处理程序:
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");
设置一个自定义的断言处理程序,将断言转换为异常,在你的 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');
在你的控制器中使用这样的包装器
public function controller_method( )
{
try
{
// normal flow
}
catch( Exception $e )
{
log_message( 'error', $e->getMessage( ) . ' in ' . $e->getFile() . ':' . $e->getLine() );
// on error
}
}
您可以根据自己的喜好调整和定制整个事情!
希望这可以帮助。
您还需要拦截 CI show_error 方法。将它放在 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 );
}
}
并在 application/config/database.php 中将此设置保留为 FALSE,以便将数据库错误转换为异常。
$db['default']['db_debug'] = TRUE;
CI 有一些(非常)弱点,例如异常处理,但这将大大有助于纠正这一点。
如果要使用事务,请确保对异常进行回滚。与此相关的从不(如在 EVER 中)使用持久连接作为打开的事务,其他会话特定的数据库状态将被其他会话拾取/继续。