2012-03-19 45 views
1

我的应用程序有一个注册的关闭功能,似乎有一些问题与我的方法与try/catch使用异常退出应用程序(而不是使用exit()方法由于FastCGI不喜欢这个)。使用异常退出PHP应用程序

我的问题是,如果try/catch块中不是ExitApp异常引发另一个异常,它会导致一些意外的结果,最终结果是ExitApp异常未被捕获。

我在PHP 5.3.6上看到这个,现在要在另一个版本上测试它,但我很好奇,如果任何人都可以立即指出这里有什么问题。

<?php 

// Define dummy exception class 
class ExitApp extends Exception {} 

try { 
    // Define shutdown function 
    function shutdown() { 
     echo "Shutting down..."; 
     throw new ExitApp; 
    } 

    register_shutdown_function("shutdown"); 

    // Throw exception! 
    throw new Exception("EXCEPTION!"); 
} catch(ExitApp $e) { 
    echo "Catching the exit exception!"; 
} 

/** 
* Expected Result: Uncaught Exception Error and then "Catching the exit exception!" is printed. 
* Actual Result: Uncaught Exception Error for "Exception" and then Uncaught Exception Error for "ExitApp" even though it's being caught. 
*/ 

回答

0

您对代码有错误的期望。首先,如果在关闭函数中抛出异常,那么最终会导致未捕获的异常 - 在tr/catch块之外调用关闭函数。

其次你没有试图拦截未知的异常 - 你只能捕获ExitApp类型。你可能想尝试这样的事情:

try { 
    //some stuff 
} catch(ExitApp $ea) { 
    //normal exit, nothing to do here 
} catch(Exception $e){ 
    //something rather unexpected, log it 
} 
+0

示例代码已经过调整以更好地反映我的真实情况。至于捕捉其他异常,这是重点。我只想捕捉ExitApp异常并且不执行任何操作。所有其他异常将被全局异常处理程序捕获。 – saverio 2012-03-19 18:34:34

+0

您的更改变化不大。第一次使用关闭功能时引发异常,而不是定义函数的位置。更重要的是,关闭函数在退出,致命错误和未捕获异常之后被调用,因此您不应该将其注册为关闭函数。让脚本正常进行到最后,并在必要时抛出它。如果我理解正确,只要在注册为shutdown的地方调用'shutdown()',那么任何代码都不会被执行,所以不会有未捕获的异常。 – 2012-03-19 18:43:26

+0

看来这里面临的更大问题是异常无法通过关闭函数内的try/catch捕获。看起来,当关闭功能被调用时,它们将不在标准范围内。我在设计这个解决方案时并没有意识到。 – saverio 2012-03-19 19:19:53

0

关机()函数甚至没有在try/catch块,所以它永远不会跳下来捕捉这个异常类型。它将在出口上运行,这样您就不会再在该try/catch块中。

在更精神上,try/catch并不意味着流量控制。我不太确定你为什么试图抛出这个脚本来导致脚本退出,而不是仅仅调用你自己的shutdown()方法。

希望有所帮助。

+0

该代码仅仅是这篇文章嘲讽的样本,但你在所有方面都是正确的。永远不要少,它不能解决我的任何问题。我没有调用我自己的shutdown()方法的原因是因为如果我在我的应用程序内部深处并且想要退出应用程序,那么必须调用exit(),否则脚本将继续运行。正如我上面所解释的,当您的应用程序通过FastCGI运行时调用exit()并不会很好。 Python使用SystemExit异常,并将该概念移植到PHP。它运作良好;但是,在这种情况下,并非如此。 – saverio 2012-03-19 18:25:35