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树的代码,可以嵌套任意层
Oct 09 PHP
《PHP边学边教》(04.编写简易的通讯录――视频教程1)
Dec 13 PHP
根据中文裁减字符串函数的php代码
Dec 03 PHP
Server.HTMLEncode让代码在页面里显示为源代码
Dec 08 PHP
使用PHP强制下载PDF文件示例
Jan 17 PHP
php使用pack处理二进制文件的方法
Jul 03 PHP
国产PHP开发框架myqee新手快速入门教程
Jul 14 PHP
PHP用反撇号执行外部命令
Apr 14 PHP
PHP中SSO Cookie登录分析和实现
Nov 06 PHP
Yii2.0使用阿里云OSS的SDK上传图片、下载、删除图片示例
Sep 20 PHP
php删除一个路径下的所有文件夹和文件的方法
Feb 07 PHP
php面试中关于面向对象的相关问题
Feb 13 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流Streams、包装器wrapper概念与用法实例详解
2017/11/17 PHP
js分解url参数(面向对象-极简主义法应用)
2012/08/09 Javascript
一个检测表单数据的JavaScript实例
2014/10/31 Javascript
jQuery实现鼠标滑过Div层背景变颜色的方法
2015/02/17 Javascript
JavaScript实现向右伸出的多级网页菜单效果
2015/08/25 Javascript
jquery ztree异步搜索(搜叶子)实践
2016/02/25 Javascript
jQuery实现鼠标选文字发新浪微博的方法
2016/04/02 Javascript
easyui window refresh 刷新两次的解决方法(推荐)
2016/05/18 Javascript
AngularJS包括详解及示例代码
2016/08/17 Javascript
教你5分钟学会用requirejs(必看篇)
2017/07/25 Javascript
基于react组件之间的参数传递(详解)
2017/09/05 Javascript
vue轻量级框架无法获取到vue对象解决方法
2019/05/12 Javascript
js笔试题-接收get请求参数
2019/06/15 Javascript
vue实现滑动超出指定距离回顶部功能
2019/07/31 Javascript
解决layui的table插件无法多层级获取json数据的问题
2019/09/19 Javascript
[01:13]2014DOTA2西雅图邀请赛 舌尖上的TI4
2014/07/08 DOTA
[55:03]LGD vs EG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
python使用webbrowser浏览指定url的方法
2015/04/04 Python
Python的Socket编程过程中实现UDP端口复用的实例分享
2016/03/19 Python
详解Python如何获取列表(List)的中位数
2016/08/12 Python
在Python中通过getattr获取对象引用的方法
2019/01/21 Python
python分数表示方式和写法
2019/06/26 Python
Python GUI库PyQt5样式QSS子控件介绍
2020/02/25 Python
python图片验证码识别最新模块muggle_ocr的示例代码
2020/07/03 Python
python时间time模块处理大全
2020/10/25 Python
Clarisonic美国官网:科莱丽声波洁面仪
2017/10/12 全球购物
土木工程毕业生自荐信
2013/09/21 职场文书
财务管理个人自荐书范文
2013/11/24 职场文书
好军嫂事迹材料
2014/01/15 职场文书
三项教育活动实施方案
2014/03/30 职场文书
教师自我剖析材料(四风问题)
2014/09/30 职场文书
工程部岗位职责
2015/02/10 职场文书
2015年社区统计工作总结
2015/04/21 职场文书
Python基础知识之变量的详解
2021/04/14 Python
快速学习Oracle触发器和游标
2021/06/30 Oracle
css3应用示例:新增的选择器
2022/03/16 HTML / CSS