在PHP/CodeIgniter中捕获意外终止

在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

我正在使用CodeIgniter托管RESTful API,我希望捕获任何不返回预期状态代码的API响应。用一个例子很容易解释这一点。通常,我的代码如下所示:

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;