在PHP/CodeIgniter中捕获意外终止
我正在使用CodeIgniter托管RESTful API,我希望捕获任何不返回预期状态代码的API响应。用一个例子很容易解释这一点。通常,我的代码如下所示:在PHP/CodeIgniter中捕获意外终止,php,api,codeigniter,rest,Php,Api,Codeigniter,Rest,我正在使用CodeIgniter托管RESTful API,我希望捕获任何不返回预期状态代码的API响应。用一个例子很容易解释这一点。通常,我的代码如下所示: function post_comment() { $comment = $_POST['comment']; $result = do_something_with_comment($comment); if ($result === true) { return_json_r
function post_comment()
{
$comment = $_POST['comment'];
$result = do_something_with_comment($comment);
if ($result === true)
{
return_json_response(200, 'OK!');
}
else
{
return_json_response(400, 'Something terrible happened...');
}
}
返回200或400是完全有效的。我的问题是:如果do_something_with_comment()出现致命错误,或者如果我在do_something_with_comment()中留下打印调试,如何捕获错误。在前一种情况下,我永远不会到达return\u json\u response()。在后一种情况下,我将访问它,但屏幕调试将破坏JSON响应
有没有办法创建一个通用包装器来捕获任何意外的输出或终止?有一个函数,您可以为每个脚本设置自己的关闭处理程序。在那里做你需要的
顺便说一句:让你的脚本尽可能防弹。您的脚本不应该有致命错误、SEGFULTS或类似的运行时错误。任何响应,即使对客户端无效,在请求处理上下文中也是有效的。我鼓励您查看Symfony2框架或其/HttpFoundation组件,因为它们将此过程完美地包装在友好的界面中。通常您可以:
尽可能多地使用异常/异常处理
注册一个将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中:
并在application/config/database.php中将此设置保留为FALSE,以便将数据库错误转换为异常
CI有一些(非常)弱点,例如异常处理,但这将大大改善这一点。哇,这比我预期的要出色得多。:)我将尝试所有这些方法。一般来说,我的代码具有良好的错误处理能力,但我还不能在知道所有内容都被正确捕获的情况下晚上睡觉。谢谢你,帕特里克!好的,为了完全正确地执行,您还必须捕获CI-DB错误。我将编辑答案并添加它!我按原样添加了您的代码,它完全可以开箱即用。:)我的DB错误现在通过我的API以状态400返回。(并不是说我想让我的最终消费者看到这一点,但这只是一个开始)现在我只需要更好地理解你给我的东西并定制它。非常感谢!一个简单的问题:log_message()将数据写入哪里?我假设路径在一个配置文件中?编辑忽略。它位于config.php中。最后一个问题:您知道扩展log_message()的安全方法吗?如果类型为“错误”,我希望它通过电子邮件向我发送完整的例外情况。一般来说,我想知道错误并立即修复它们,所以我可以接受垃圾邮件。这是一个好主意-我也会尝试一下!我看过Symfony,我认为现在的学习曲线和开销对我来说有点太高了。我已经在CodeIgniter上投资了一年。:)
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 );
}
}
$db['default']['db_debug'] = TRUE;