php CodeIgniter:Try Catch 在模型类中不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15858372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CodeIgniter: Try Catch is not working in model class
提问by Himanshu Yadav
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:
我unique
对列有一个限制。当此代码运行时,我从框架中获取错误日志,但这不是我在 Exception 块中给出的。
如果存在唯一列,那么我想查询其主键并将其设置为$id
并返回页面。现在它在 db 错误上停止而不是进入Catch block
.
这是我的代码:
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:
**Error Messages**
我从框架中得到:
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.
我不知道这有什么问题。
回答by Patrick Savalle
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.
CI 对异常没有很好的支持。您的数据库查询会调用一些模糊的 CI error_logging 东西,称为 show_error()。您需要做的是设置适当的异常处理。
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.
现在你所有的数据库错误都会自动抛出异常。作为奖励,您可以在整个 CI 应用程序中进行良好的异常处理。
Register a custom errorhandler that transforms PHP errors into exceptions, for instance put this in top of your config/config.php
注册一个将 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");
Register an uncaught exception handler, put something like this in your config/config.php
注册一个未捕获的异常处理程序,在你的 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:
设置一个自定义断言处理程序,将断言转换为异常,在你的 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:
您还需要拦截 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 );
}
}
And leave in application/config/database.php this setting on FALSE to have database errors converted into exceptions.
并在 application/config/database.php 中将此设置保留为 FALSE 以将数据库错误转换为异常。
$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.
CI 有一些(非常)弱点,例如异常处理,但这将大大纠正这一点。
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.
如果您打算使用事务,请确保对异常进行回滚。与此相关的 NEVER(如在 EVER 中)使用持久连接作为打开的事务和其他会话特定的 DB 状态将被其他会话拾取/继续。
回答by Aken Roberts
If database debugging is turned on, errors from the DB will be routed to the Exceptions core class, and exit()
is called after, meaning the script will never even reach your if
conditional.
如果打开数据库调试,来自数据库的错误将被路由到 Exceptions 核心类,并exit()
在之后调用,这意味着脚本甚至永远不会达到您的if
条件。
Open application/config/database.php
and try setting db_debug
to false. This is a good idea to do for production websites, anyways, because you don't want any SQL query issues to release info about your database structure.
打开application/config/database.php
并尝试设置db_debug
为 false。无论如何,这对于生产网站来说是一个好主意,因为您不希望任何 SQL 查询问题发布有关您的数据库结构的信息。
Also, unrelated, be careful using $
inside of double quotes, because it'll get parsed as a variable (even a bunch of them in a row -- it'll literally be a variable variable variable variable ...).
另外,不相关的,$
在双引号内使用时要小心,因为它会被解析为一个变量(即使是一堆连续的 - 它实际上是一个变量变量变量变量......)。
回答by JohnnyCoder
What if you set the result outside the try
block? Or an ternary operator:
如果将结果设置在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;
}
It's hard to know without knowing what the value of $result
really is, like @jcorry said.
$result
正如@jcorry 所说,如果不知道真正的价值是什么,就很难知道。
回答by realkyo
$db['default']['db_debug'] = FALSE;
https://forum.codeigniter.com/archive/index.php?thread-8484.html
https://forum.codeigniter.com/archive/index.php?thread-8484.html
回答by OwChallie
If you look into CodeIgniter's code, you will see that it has its own error handling set up in CodeIgniter.php in bot system/core and ci_system/core folders.
如果您查看 CodeIgniter 的代码,您会发现它在 bot system/core 和 ci_system/core 文件夹中的 CodeIgniter.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');
The first two functions deal with the error handling. In order to get your try..catch block to work, you just need to turn this off.
前两个函数处理错误处理。为了让你的 try..catch 块工作,你只需要关闭它。
Using the restore_error_handlerand restore_exception_handlerfunctions, we can reset these error handling functions back to default.
使用restore_error_handler和restore_exception_handler函数,我们可以将这些错误处理函数重置为默认值。
restore_error_handler();
restore_exception_handler();
or... if you want to preserve the error handlers to restore them later.
或者...如果您想保留错误处理程序以在以后恢复它们。
//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);
}
}
We can disable all the custom error handlers and store them to be restored if desired.
如果需要,我们可以禁用所有自定义错误处理程序并存储它们以进行恢复。
I use the loops when saving and restoring in case there are other error handlers set up. This way, you restore all the error handlers as there may be similar code elsewhere that goes back to a previous error handler for some specific purpose and it will be preserved.
我在保存和恢复时使用循环,以防设置其他错误处理程序。通过这种方式,您可以恢复所有错误处理程序,因为其他地方可能存在类似的代码,这些代码出于某些特定目的返回到先前的错误处理程序,并且将被保留。