我试图了解在以下情况下处理异常的最佳方法是什么:
我有一个班级员工:
class employee extends person {
private $salary;
private $baseSalary = 6.5;
function __construct($f, $m, $l, $a,$fsalary=0){
if(!is_numeric($fsalary)){
throw new Exception("Age supplied is not a number", 114);
}
parent::__construct($f, $m, $l, $a);
$this->salary=$fsalary;
}
function GetDetails(){
return parent::GetName().
"<br/>".
$this->salary;
}
function __toString(){
return $this->GetDetails();
}
}
并使用它:
try{
if(!$f = new employee("Sarah", "Sebastian", "Pira", "abc")){
throw new Exception();
}
else {
echo $f;
}
}
catch (Exception $e){
echo "<br/>";
echo var_dump($e);
}
现在我认为在类中抛出异常,然后在所有使用员工对象的脚本中只使用一个 catch 块是个好主意 - 但这似乎不起作用 - 我需要在类中有一个尝试的 catch 块 - 这是看待这个问题的正确方法吗?
谢谢
我想你的意思是你想做这样的事情:
try {
class Employee extends Person {
// ...blah blah...
}
}
catch(Exception $e) {
// handle exception
}
。然后能够在其他类中取消它,而不会显式捕获任何异常:
// try { << this would be removed
$employee = new Employee();
// }
// catch(Exception $e) {
// (a whole bunch of code to handle the exception here)
// }
你不能这样做,因为这样类中的 try/catch 块只会捕获定义类时发生的任何异常。当您尝试实例化它时,它们不会被捕获,因为您的new Employee
行在 try/catch 块之外。
所以实际上,你的问题是你希望能够在多个地方重用try/catch块,而无需重写代码。在这种情况下,最好的解决方案是将 catch 块的内容移出到一个单独的函数中,您可以根据需要调用该函数。在 Employee 类文件中定义函数并像这样调用它:
try {
$employee = new Employee();
$employee->doSomeStuff();
$employee->doMoreStuffThatCouldThrowExceptions();
}
catch(Exception $e) {
handle_employee_exception($e);
}
它不会删除每个文件中的try/catch块,但它确实意味着您不必一直重复异常处理的实现。并且不要将handle_employee_exception定义为类的实例方法,将其作为单独的函数进行,否则如果在构造函数中抛出异常,则会导致致命错误,因为变量将不存在。
你应该阅读更多关于 PHP 中的异常。
当然,您可以在类的方法中处理异常。但是你应该重新考虑你想如何做到这一点,并且......为什么。
好的做法是创建自己的异常类,这样你就可以区分模块/类抛出的异常和其他东西抛出的异常。它看起来像这样(查看更多):
class EmployeeModule_Exception extends Exception {}
当涉及到抛出异常时:
// the second parameter below is error code
throw new EmployeeModule_Exception('some message', 123);
捕获是类似的,只有下面的示例只会捕获模块的异常:
try {
// some code here
} catch (EmployeeModule_Exception $e) {
// display information about exception caught
echo 'Error message: ' . $e->getMessage() . '<br />';
echo 'Error code: ' . $e->getCode();
}