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 相关文章推荐
PHP函数utf8转gb2312编码
Dec 21 PHP
PHP+MySQL 手工注入语句大全 推荐
Oct 30 PHP
PHP sprintf()函数用例解析
May 18 PHP
介绍一些PHP判断变量的函数
Apr 24 PHP
PHP提示Cannot modify header information - headers already sent by解决方法
Sep 22 PHP
PHP动态编译出现Cannot find autoconf的解决方法
Nov 05 PHP
两个php日期控制类实例
Dec 09 PHP
PHP的PDO常用类库实例分析
Apr 07 PHP
Redis使用Eval多个键值自增的操作实例
Nov 04 PHP
浅谈PHP的反射API
Feb 26 PHP
PHP常见的几种攻击方式实例小结
Apr 29 PHP
PHP cookie与session会话基本用法实例分析
Nov 18 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
关于PHP5 Session生命周期介绍
2010/03/02 PHP
浅析php数据类型转换
2014/01/09 PHP
php中有关合并某一字段键值相同的数组合并的改进
2015/03/10 PHP
深入浅析yii2-gii自定义模板的方法
2016/04/26 PHP
yii2使用ajax返回json的实现方法
2016/05/14 PHP
验证用户是否修改过页面的数据的实现方法
2008/09/26 Javascript
jquery ajax提交表单数据的两种方式
2009/11/24 Javascript
弹出层之1:JQuery.Boxy (一) 使用介绍
2011/10/06 Javascript
JavaScript之自定义类型
2012/05/04 Javascript
9行javascript代码获取QQ群成员具体实现
2013/10/16 Javascript
JavaScript 变量、作用域及内存
2015/04/08 Javascript
jQuery手指滑动轮播效果
2016/12/22 Javascript
JavaScript 详解预编译原理
2017/01/22 Javascript
vue.js的提示组件
2017/03/02 Javascript
详解webpack es6 to es5支持配置
2017/05/04 Javascript
js自定义input文件上传样式
2018/10/26 Javascript
微信小程序实现的3d轮播图效果示例【基于swiper组件】
2018/12/11 Javascript
vue+element+Java实现批量删除功能
2019/04/08 Javascript
javascript实现固定侧边栏
2021/02/09 Javascript
Python修改Excel数据的实例代码
2013/11/01 Python
RC4文件加密的python实现方法
2015/06/30 Python
整理Python 常用string函数(收藏)
2016/05/30 Python
解决安装python3.7.4报错Can''t connect to HTTPS URL because the SSL module is not available
2019/07/31 Python
Django admin管理工具TabularInline类用法详解
2020/05/14 Python
python如何爬取网页中的文字
2020/07/28 Python
详解PyQt5中textBrowser显示print语句输出的简单方法
2020/08/07 Python
一款纯css3实现的鼠标经过按钮特效教程
2014/11/09 HTML / CSS
美国定制钻石订婚戒指:Ritani
2017/12/08 全球购物
Internet体系结构
2014/12/21 面试题
毕业生自我鉴定范文
2013/11/08 职场文书
商务英语毕业生自荐信范文
2013/11/08 职场文书
材料物理专业个人求职信
2013/12/15 职场文书
大学生演讲稿范文
2014/01/11 职场文书
2014年综合治理工作总结
2014/11/20 职场文书
2014年幼儿园教学工作总结
2014/12/04 职场文书
Django程序的优化技巧
2021/04/29 Python