Php CodeIgniter:Try Catch在模型类中不起作用
我对列的属性有一个Php CodeIgniter:Try Catch在模型类中不起作用,php,codeigniter,Php,Codeigniter,我对列的属性有一个唯一的约束。当这段代码运行时,我从框架中得到错误日志,但它不是我在异常块中给出的 如果存在唯一列,则我希望查询其主键并将其设置为$id,然后返回页面。现在,它在db错误时停止,而不是进入捕获块 这是我的代码: try { $result = $this->db->insert('email', $new_email); if ($result) { $id = $
唯一的约束。当这段代码运行时,我从框架中得到错误日志,但它不是我在异常块中给出的
如果存在唯一列,则我希望查询其主键并将其设置为$id
,然后返回页面。现在,它在db错误时停止,而不是进入捕获块
这是我的代码:
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;
}
**错误消息**
我从框架中获得:
DEBUG - 2013-04-07 05:00:38 --> DB Transaction Failure
ERROR - 2013-04-07 05:00:38 --> Query error: Duplicate entry
我不知道它出了什么问题。如果打开数据库调试,数据库中的错误将被路由到Exceptions核心类,然后调用exit()
,这意味着如果有条件,脚本将永远不会到达您的
打开application/config/database.php
并尝试将db_debug
设置为false。无论如何,这对于生产网站来说是一个好主意,因为您不希望任何SQL查询问题发布有关数据库结构的信息
另外,在双引号内使用$
时要小心,因为它会被解析为一个变量(甚至是一行中的一堆变量——它实际上是一个变量…)。如果将结果设置在try
块之外会怎么样?或三元运算符:
$result = $this->db->insert('email', $new_email);
try {
$result = ($result) ? $result || false;
if ($result) {
$id = $this->db->insert_id();
} else {
throw new Exception("$$$$$$$$$$$$$Log database error");
}
} catch (Exception $e) {
log_message('error',$e->getMessage());
return;
}
正如@jcorry所说,如果不知道$result
的实际值是什么,很难知道。CI对异常没有很好的支持。DB查询将调用一些模糊的CI错误记录内容,称为show\u error()。您需要做的是设置正确的异常处理
基本上你可以按照整个食谱来做
现在,所有数据库错误都将自动抛出异常。作为奖励,您在整个CI应用程序中具有良好的异常处理能力
注册一个将PHP错误转换为异常的自定义errorhandler,例如,将其放在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");
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");
注册一个未捕获的异常处理程序,在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");
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");
在控制器中使用这样的包装器
$db['default']['db_debug'] = TRUE;
您可以根据自己的喜好调整和定制整个内容
希望这有帮助
您还需要截取CI show_error方法。将其放在application/core/MY_exceptions.php中:
/*
* ------------------------------------------------------
* Define a custom error handler so we can log PHP errors
* ------------------------------------------------------
*/
set_error_handler('_error_handler');
set_exception_handler('_exception_handler');
register_shutdown_function('_shutdown_handler');
并在application/config/database.php中将此设置保留为FALSE,以便将数据库错误转换为异常
restore_error_handler();
restore_exception_handler();
CI有一些(非常)弱点,例如异常处理,但这将大大改善这一点
如果要使用事务,请确保对异常执行回滚。与此相关的是,从不(像以前一样)将持久性连接用作打开的事务,其他会话将拾取/继续其他会话特定的DB状态 如果查看CodeIgniter的代码,您将看到它在bot system/core和ci_system/core文件夹中的CodeIgniter.php中设置了自己的错误处理
//Disable CodeIgniter error handling so we can use try catch blocks
$errorHandlers = array();
do {
$errorHandler = set_error_handler(function() {}); //Get the current handler
array_push($errorHandlers, $errorHandler); //Store the handler so that it can be restored if necessary
for ($i = 0; $i < 2; $i++) { //We have to reset twice to get to the previous handler since we added a dummy handler
restore_error_handler();
}
}
while (!is_null($errorHandler)); //Is null when there are no handlers
$exceptionHandlers = array(); //Do the same with exceptions
do {
$exceptionHandler = set_exception_handler(function() {});
array_push($exceptionHandlers, $exceptionHandler);
for ($i = 0; $i < 2; $i++) {
restore_exception_handler();
}
}
while (!is_null($exceptionHandler));
try {
//Your code goes here
}
catch (Error $e) {
//Handle error
}
catch (Exception $e) {
//Handle exception
}
//Restore all error handlers
foreach ($errorHandlers as $errorHandler) {
if (isset($errorHandler)) {
set_error_handler($errorHandler);
}
}
foreach ($exceptionHandlers as $exceptionHandler) {
if (isset($exceptionHandler)) {
set_exception_handler($exceptionHandler);
}
}
前两个函数处理错误处理。为了让您的try..catch块工作,您只需关闭此功能
使用和函数,我们可以将这些错误处理函数重置为默认值
$db['default']['db_debug'] = FALSE;
或者。。。如果要保留错误处理程序以在以后还原它们
//禁用CodeIgniter错误处理,以便我们可以使用try-catch块
$errorHandlers=array();
做{
$errorHandler=set_error_handler(function(){});//获取当前处理程序
array_push($errorHandlers,$errorHandler);//存储处理程序,以便在必要时可以还原它
对于($i=0;$i<2;$i++){//我们必须重置两次才能访问上一个处理程序,因为我们添加了一个虚拟处理程序
还原错误处理程序();
}
}
而(!is_null($errorHandler))//如果没有处理程序,则为null
$exceptionHandlers=array()//对例外情况也要这样做
做{
$exceptionHandler=设置异常处理程序(函数(){});
数组_push($exceptionHandler,$exceptionHandler);
对于($i=0;$i<2;$i++){
还原异常处理程序();
}
}
而(!is_null($exceptionHandler));
试一试{
//你的密码在这里
}
捕获(错误$e){
//处理错误
}
捕获(例外$e){
//处理异常
}
//还原所有错误处理程序
foreach($errorHandler作为$errorHandler){
if(isset($errorHandler)){
设置错误处理程序($errorHandler);
}
}
foreach($exceptionHandler作为$exceptionHandler){
if(isset($exceptionHandler)){
设置异常处理程序($exceptionHandler);
}
}
我们可以禁用所有自定义错误处理程序,并存储它们,以便在需要时进行恢复
我在保存和还原时使用循环,以防设置了其他错误处理程序。通过这种方式,您可以恢复所有错误处理程序,因为其他地方可能存在类似的代码,这些代码出于某些特定目的返回到以前的错误处理程序,并且将被保留
您能更具体地描述一下哪些不起作用吗?发生了什么而不是你期望的?也许$result不是假的?
//Disable CodeIgniter error handling so we can use try catch blocks
$errorHandlers = array();
do {
$errorHandler = set_error_handler(function() {}); //Get the current handler
array_push($errorHandlers, $errorHandler); //Store the handler so that it can be restored if necessary
for ($i = 0; $i < 2; $i++) { //We have to reset twice to get to the previous handler since we added a dummy handler
restore_error_handler();
}
}
while (!is_null($errorHandler)); //Is null when there are no handlers
$exceptionHandlers = array(); //Do the same with exceptions
do {
$exceptionHandler = set_exception_handler(function() {});
array_push($exceptionHandlers, $exceptionHandler);
for ($i = 0; $i < 2; $i++) {
restore_exception_handler();
}
}
while (!is_null($exceptionHandler));
try {
//Your code goes here
}
catch (Error $e) {
//Handle error
}
catch (Exception $e) {
//Handle exception
}
//Restore all error handlers
foreach ($errorHandlers as $errorHandler) {
if (isset($errorHandler)) {
set_error_handler($errorHandler);
}
}
foreach ($exceptionHandlers as $exceptionHandler) {
if (isset($exceptionHandler)) {
set_exception_handler($exceptionHandler);
}
}
$db['default']['db_debug'] = FALSE;