PHP核心技术——异常和错误处理

  • PHP只有手动抛出异常后才能捕获异常
$a = null;
try {
    $a = 5/0;
    echo $a,PHP_EOL;
} catch (exception $e) {
    $e -> getMessage();
    $a = -1;
}
echo $a;
  • 对于除零这种“异常”情况,PHP认为这是一个错误,直接触发错误(warning也是错误,只是错误等级不一样),而不会自动抛出异常使程序进入异常流程,故最终a值并不是预想中的-1,也就是说,并没有进入异常分支,也没有处理异常。
// 先定义两个异常类,它们需要继承自系统的exception
class emailException extends exception{

}

class pwdException extends exception{
    function __toString(){
        return "<div clas=\"error\">Exception{$this->getCode()}:
        {$this->getMessage()}
        in File:{$this->getFile()}on line:{$this->getLine()}</div>";
        //改写抛出异常结果
    }
}
// 根据业务需求抛出不同异常
function reg($reginfo=null){
    if (empty($reginfo)||!isset($reginfo)) {
        throw new Exception("参数非法");
    }
    if (empty($reginfo['email'])) {
        throw new emailException("邮件为空");
    }
    if ($reginfo['pwd']!=$reginfo['repwd']) {
        throw new pwdException("两次密码不一致");
    }
    echo '注册成功';
}
// 对异常进行分拣并做处理
try {
    reg(array('email'=>'waitfox@qq.com','pwd'=>123456,'repwd'=>12345678));
    // reg();
}catch (emailException $ee) {
    echo $ee->getMessage();
}catch(pwdException $ep){
    echo $ep;
    echo PHP_EOL,'特殊处理';
}catch(Exception $e){
    echo $e->getTraceAsString();
    echo PHP_EOL,'其他情况,统一处理';
  • 在下面三种场景下会用到异常处理机制:1.对程序的悲观预测;2.程序的需要和对业务的关注;3.语言级别的健壮性要求

  • PHP中的异常机制是不足的,绝大多数情况下无法自动抛出异常,必须用if……else先进行判断,再手动抛出异常。手动抛异常的意义不是很大,因为这意味着在代码里已经充分预期到错误的出现,也就算不上真正的“异常”,而是意料之中。同时,这种方式还会使你陷入纷繁复杂的业务逻辑判断和处理中。

  • PHP错误就是会使脚本运行不正常的情况

  • 错误大致分为以下几类。

  • deprecated是最低级别的错误,表示“不推荐,不建议”。比如在PHP 5中使用ereg系列的正则匹配函数就会报此类错误。这种错误一般由于使用不推荐的、过时的函数或语法造成的。其虽不影响PHP正常流程,但一般情况下建议修正。

  • 其次是notice。这种错误一般告诉你语法中存在不当的地方。如使用变量但是未定义就会报此错。最常见的,数组索引是字符时没有加引号,PHP就视为一个常量,先查找常量表,找不到再视为变量。虽然PHP是脚本语言,语法要求不严,但是仍然建议对变量进行初始化。这种错误不影响PHP正常流程。

  • warning是级别比较高的错误,在语法中出现很不恰当的情况时才会报此错误,比如函数参数不匹配。这种级别的错误会导致得不到预期结果,故需要修改代码。

  • 更高级别的错误是fetal error。这是致命错误,直接导致PHP流程终结,后面的代码不再执行。这种问题非改不可。

  • 最高级别的错误是语法解析错误prase error。上面提到的错误都属于PHP代码运行期间错误,而语法解析错误属于语法检查阶段错误,这将导致PHP代码无法通过语法检查。错误级别不止这几个,最主要的都在前面提到了。PHP手册中一共定义了16个级别的错误,最常用的就这几个。

  • 在代码质量或者环境不可控时(比如数据库连接失败),使用error_reporting(0),这样就能屏蔽错误了,正式部署时可以采取这样的策略,防止错误消息泄露敏感信息。另外一个技巧就是在函数前加@符号,抑制错误信息输出,如@mysql_connect()。


参考资料

  • [PHP核心技术与最佳实践]
posted @ 2019-03-27 15:17  高级生命体  阅读(290)  评论(0编辑  收藏  举报