PHP批斗大会之缺失的异常详解


Posted in PHP onJuly 09, 2019

故事的开始

这几天观察错误日志发现有一个数据反序列化的notice错误,实际情况我是从缓存中读取数据然后反序列化,因为反序列化失败,所以实际每次都是去数据库取的值。背后性能影响还是挺大的。

缺失的异常

刚开始写代码的时候一直不明白为什么要用异常,感觉if else就能搞定了,为什么还要多此一举,现在反而觉得 php 的异常太少。

对比两种序列化场景,一个是json,另一个是serialize。

json

在json encode/decode的时候,如果出现异常,可以通过json_last_error()来获取。

https://www.php.net/manual/en...

这样的设计只能说勉强够用,不太符合面向对象的套路。

serialize/unserialize

在使用自带的序列化和反序列化的时候,相比json的处理,则更加简单粗暴,没有函数能拿到最后的错误,只会通过自定义的error handler来接管,然后自己去做出一些相应的处理。

为什么要捕获异常

比如我的代码比较乱,有的 key 是 json 序列化,有的 key 是 serialize。我们可以将 key 分类。不能确保其他人配置的对应关系是对的,或者有的人忘记了,所以我需要用捕获异常的方式来兜底,这样我们的代码更加健壮一些。当unserialize失败之后,我们可以尝试去json_decode,而不是立即返回一个false,从而把请求传递到数据库。

代码演示

error_reporting(E_ALL);

$a = ["a" => 1];

class UnSerializeException extends ErrorException
{

}

set_error_handler(function ($severity, $message, $file, $line) {
  $info = explode(":", $message);

  if ($severity == E_NOTICE) {
    if ($info[0] == "unserialize()") {
      throw new UnSerializeException($message);
    }
    return true;
  } else {

    throw new ErrorException($message, 0, $severity, $file, $line);;
  }
});


try {
  $b = unserialize(json_encode($a));
} catch (ErrorException $exception) {
  var_dump(get_class($exception), $exception->getMessage(), $exception->getTraceAsString()); // 捕获到了
} finally {
  restore_error_handler();
}

try {
  $b = unserialize(json_encode($a));
} catch (ErrorException $exception) {
  var_dump(get_class($exception), $exception->getMessage(), $exception->getTraceAsString()); // 无法捕获
}

输出结果

string(20) "UnSerializeException"
string(43) "unserialize(): Error at offset 0 of 7 bytes"
string(181) "#0 [internal function]: {closure}(8, 'unserialize(): ...', '/Users/mengkang...', 34, Array)
#1 /Users/mengkang/PhpstormProjects/xxx/test.php(34): unserialize('{"a":1}')
#2 {main}"

Notice: unserialize(): Error at offset 0 of 7 bytes in /Users/mengkang/PhpstormProjects/xxx/test.php on line 42

后记

所以 php 代码的异常设计还是任重而道远的,而这些已经设定的“旧的规范”要推翻,需要“勇气”,毕竟会影响所有的使用者。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
第六节--访问属性和方法
Nov 16 PHP
解析yahoo邮件用phpmailer发送的实例
Jun 24 PHP
PHP 关于访问控制的和运算符优先级介绍
Jul 08 PHP
PHP如何利用P3P实现跨域
Aug 24 PHP
php加密算法之实现可逆加密算法和解密分享
Jan 21 PHP
php根据一个给定范围和步进生成数组的方法
Jun 19 PHP
php组合排序简单实现方法
Oct 15 PHP
php变量与数组相互转换的方法(extract与compact)
Dec 02 PHP
简单解决微信文章图片防盗链问题
Dec 17 PHP
PHP生成随机数的方法总结
Mar 01 PHP
php设计模式之装饰模式应用案例详解
Jun 17 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
Feb 22 PHP
PHP结合Redis+MySQL实现冷热数据交换应用案例详解
Jul 09 #PHP
PHP+Redis开发的书签案例实战详解
Jul 09 #PHP
使用composer命令加载vendor中的第三方类库 的方法
Jul 09 #PHP
Laravel+Intervention实现上传图片功能示例
Jul 09 #PHP
Laravel框架实现多个视图共享相同数据的方法详解
Jul 09 #PHP
Laravel5.1框架注册中间件的三种场景详解
Jul 09 #PHP
PHP使用 Pear 进行安装和卸载包的方法详解
Jul 08 #PHP
You might like
PHP判断JSON对象是否存在的方法(推荐)
2016/07/06 PHP
PHP简单遍历对象示例
2016/09/28 PHP
php+webSoket实现聊天室示例代码(附源码)
2017/02/17 PHP
PHP bin2hex()函数基础实例讲解
2019/02/11 PHP
php实现多站点共用session实现单点登录的方法详解
2019/09/18 PHP
JS效率个人经验谈(8-15更新),加入range技巧
2007/01/09 Javascript
js直接编辑当前cookie的脚本
2008/09/14 Javascript
javascript eval和JSON之间的联系
2009/12/31 Javascript
纯JavaScript实现的完美渐变弹出层效果代码
2010/04/02 Javascript
jquery Mobile入门—外部链接切换示例代码
2013/01/08 Javascript
jQuery基于ajax实现页面加载后检查用户登录状态的方法
2017/02/10 Javascript
Javascript 详解封装from表单数据为json串进行ajax提交
2017/03/29 Javascript
B/S(Web)实时通讯解决方案分享
2017/04/06 Javascript
AngularJS select设置默认值的实现方法
2017/08/25 Javascript
Vue精简版风格概述
2018/01/30 Javascript
VUE脚手架具体使用方法
2019/05/20 Javascript
微信小程序使用字体图标的方法
2019/05/23 Javascript
解决vue-photo-preview 异步图片放大失效的问题
2020/07/29 Javascript
前端 javascript 实现文件下载的示例
2020/11/24 Javascript
Python 执行字符串表达式函数(eval exec execfile)
2014/08/11 Python
python读取.mat文件的数据及实例代码
2019/07/12 Python
tesserocr与pytesseract模块的使用方法解析
2019/08/30 Python
numpy.random.shuffle打乱顺序函数的实现
2019/09/10 Python
python标准库OS模块函数列表与实例全解
2020/03/10 Python
Python求凸包及多边形面积教程
2020/04/12 Python
pycharm下pyqt4安装及环境配置的教程
2020/04/24 Python
Selenium环境变量配置(火狐浏览器)及验证实现
2020/12/07 Python
纯CSS3实现圆角效果(含IE兼容解决方法)
2014/05/07 HTML / CSS
CSS3 mask 遮罩的具体使用方法
2017/11/03 HTML / CSS
网购亚洲时装、美容产品和生活百货:YesStyle
2016/09/15 全球购物
临床医师专业个人自我评价范文
2013/11/07 职场文书
总经理驾驶员岗位职责
2013/12/04 职场文书
车间班组长的职责
2013/12/13 职场文书
幼儿园的门卫岗位职责
2014/04/10 职场文书
护士上岗前培训自我鉴定
2014/04/20 职场文书
《风筝》教学反思
2016/02/23 职场文书