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截取汉字乱码问题解决方法mb_substr函数的应用
Mar 30 PHP
通过PHP的内置函数,通过DES算法对数据加密和解密
Jun 21 PHP
php中AES加密解密的例子小结
Feb 18 PHP
Codeigniter框架的更新事务(transaction)BUG及解决方法
Jul 25 PHP
php+ajax实现文章自动保存的方法
Dec 30 PHP
php实现两个数组相加的方法
Feb 17 PHP
phpMyAdmin安装并配置允许空密码登录
Jul 04 PHP
thinkPHP中分页用法实例分析
Dec 26 PHP
PHP读取文本文件并逐行输出该行使用最多的字符与对应次数的方法
Nov 25 PHP
Linux下 php7安装redis的方法
Nov 01 PHP
php和js实现根据子网掩码和ip计算子网功能示例
Nov 09 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
Nov 24 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
简单采集了yahoo的一些数据
2007/02/14 PHP
php面向对象全攻略 (六)__set() __get() __isset() __unset()的用法
2009/09/30 PHP
MySQL的FIND_IN_SET函数使用方法分享
2012/03/27 PHP
关于PHPDocument 代码注释规范的总结
2013/06/25 PHP
PHP实现文件下载详解
2014/11/27 PHP
php自定义加密与解密程序实例
2014/12/31 PHP
Discuz不使用插件实现简单的打赏功能
2019/03/21 PHP
在修改准备发的批量美化select+可修改select时,在非IE下发现了几个问题
2007/01/09 Javascript
比较简单的异步加载JS文件的代码
2009/07/18 Javascript
为什么要在引入的css或者js文件后面加参数的详细讲解
2013/05/03 Javascript
今天是星期几的4种JS代码写法
2013/09/17 Javascript
javascript中hasOwnProperty() 方法使用指南
2015/03/09 Javascript
BootstrapTable refresh 方法使用实例简单介绍
2017/02/20 Javascript
JavaScript函数的4种调用方法实例分析
2019/03/05 Javascript
React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析
2020/01/06 Javascript
JavaScript利用键盘码控制div移动
2020/03/19 Javascript
让IDE识别webpack的别名alias的实现方法
2020/05/06 Javascript
[01:56]2014DOTA2西雅图邀请赛 MVP外卡赛老队长精辟点评
2014/07/09 DOTA
[55:25]VGJ.T vs Optic Supermajor小组赛D组 BO3 第三场 6.3
2018/06/04 DOTA
Python break语句详解
2014/03/11 Python
Django框架中处理URLconf中特定的URL的方法
2015/07/20 Python
Python中的super()方法使用简介
2015/08/14 Python
python pandas 对series和dataframe的重置索引reindex方法
2018/06/07 Python
Python wxPython库使用wx.ListBox创建列表框示例
2018/09/03 Python
python 不同方式读取文件速度不同的实例
2018/11/09 Python
详解python中groupby函数通俗易懂
2020/05/14 Python
Python学习笔记之装饰器
2020/08/06 Python
瑞贝卡·泰勒官方网站:Rebecca Taylor
2016/09/24 全球购物
小学优秀教育工作者事迹材料
2014/05/09 职场文书
庆六一文艺汇演活动方案
2014/08/26 职场文书
民间个人借款协议书
2014/09/30 职场文书
教师创先争优承诺书
2015/04/27 职场文书
寒假生活随笔
2015/08/15 职场文书
python实现简单倒计时功能
2021/04/21 Python
Python音乐爬虫完美绕过反爬
2021/08/30 Python
Apache Hudi数据布局黑科技降低一半查询时间
2022/03/31 Servers