我目前在PHP工作。我正在为我正在构建的CMS开发一个错误系统(为了好玩)。对于系统中的致命错误(不是在php编译器中),我创建了一个FatalException类,它扩展了内置的Exception类。因为这些类型的错误会使系统停止运行,所以我在__construct中加入了一个exit。
class FatalException extends Exception{
public function __construct($message) {
exit("<h1 style='color:red;' >FATAL ERROR: $message </h1>");
}
}
所以在我的代码中,我会检查一些东西,比如连接到数据库,如果它不能,那么我就抛出一个FatalException("不能连接到数据库:$database_error_message")。它不会在try/catch块中。
例如,当我运行代码并且无法连接到数据库时,我在屏幕上看到的只是一个用红色大字写的句子。所以它工作得很好,但这是不好的做法/编码吗?
编辑:事实上,一开始并不是这样的。我最初记录错误,然后退出捕获区,但后来我想,如果所有致命错误都会退出,那就把in构造函数放进去。然后我注意到它实际上并没有到达捕捉区,而是离开了。因此,将语句放在try/catch块中是一种有争议的问题。这就引出了问题。
如果要在构造函数中无条件地使用exit()
,那么将其设置为构造函数并没有多大意义,更不用说将类设置为Exception
了。您可以更简单(诚实)地使用一个名为Fatal::Die($message)
的静态函数。
异常的意义在于它们描述了错误是什么(通过对不同的异常使用不同的类),并且可以被捕获——即使只是将它们记录到一个文件中并退出程序。
如果一个特定的页面,你的网站实际上可以处理良好没有数据库连接(只是错过了"最新消息"或什么)?然后它可以catch( Database_Exception $e )
并继续,而您的网站的其余部分只是直接落入最后的"哦,没有什么出错了"消息。
用红色大字显示的消息也不是一个很好的错误处理机制,因为其他人可能会使用——要么他们在你不注意的时候看到了错误的技术细节,要么你不知道出了什么问题,因为你隐藏了错误。
即使您将exit()
包装成异常的成员函数,您也不会在这里使用异常进行错误处理,而只是使用exit()
-异常永远不会抛出,PHP在此发生之前停止。
所以它工作得很好,但这是不好的做法/编码吗?
是的,这是不好的做法。如果您自己创建了一个函数,它也可以正常工作:
function error_exit($message) {
exit("<h1 style='color:red;' >FATAL ERROR: $message </h1>");
}
相反,考虑您是想使用 exceptions 还是想使用exit()
.
我认为这是个坏主意。异常需要被捕获才能正常工作。但是,您可以创建一个方法,如->error($index);它附着在你做的每件物品上。从那里,你可以通过try/catch块将错误路由到特定的类,以正确处理错误。
class TestClass
{
public function error( $index )
{
try
{
// Convert index to exception and throw it.
}
catch ( Exception $e )
{
// Handle the error
}
}
}
$a = new TestClass();
$a->error( 1000 );
请注意,这将不用于php抛出的异常,您需要单独捕获这些异常或与执行中心一起工作。