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禁止个别IP访问网站
Oct 30 PHP
一个显示效果非常不错的PHP错误、异常处理类
Mar 21 PHP
PHP函数getenv简介和使用实例
May 12 PHP
PHP使用CURL_MULTI实现多线程采集的例子
Jul 29 PHP
php面向对象值单例模式
May 03 PHP
Redis使用Eval多个键值自增的操作实例
Nov 04 PHP
php基于curl实现的股票信息查询类实例
Nov 11 PHP
Zend Framework框架实现类似Google搜索分页效果
Nov 25 PHP
总结的一些PHP开发中的tips(必看篇)
Mar 24 PHP
弹出模态框modal的实现方法及实例
Sep 19 PHP
php7新特性的理解和比较总结
Apr 14 PHP
Laravel实现通过blade模板引擎渲染视图
Oct 25 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 友好URL的实现(吐血推荐)
2008/10/04 PHP
php实现的Curl封装类Curl.class.php用法实例分析
2015/09/25 PHP
JavaScript 实现类的多种方法实例
2013/05/01 Javascript
jquery实现图片滚动效果的简单实例
2013/11/23 Javascript
Nodejs极简入门教程(二):定时器
2014/10/25 NodeJs
javascript正则表达式基础知识入门
2015/04/20 Javascript
javascript:void(0)点击登录没反应怎么解决
2015/11/13 Javascript
详解JavaScript对象类型
2016/06/16 Javascript
微信小程序 实现tabs选项卡效果实例代码
2016/10/31 Javascript
AngularJS实现动态编译添加到dom中的方法
2016/11/04 Javascript
js实现倒计时及时间对象
2016/11/15 Javascript
JS判断指定dom元素是否在屏幕内的方法实例
2017/01/23 Javascript
使用async-validator编写Form组件的方法
2018/01/10 Javascript
jQuery中的类名选择器(.class)用法简单示例
2018/05/14 jQuery
在layui下对元素进行事件绑定的实例
2019/09/06 Javascript
Vue中常用rules校验规则(实例代码)
2019/11/14 Javascript
JS实现碰撞检测效果
2020/03/12 Javascript
学习 Vue.js 遇到的那些坑
2021/02/02 Vue.js
[02:10]DOTA2亚洲邀请赛 EG战队出场宣传片
2015/02/07 DOTA
python MySQLdb Windows下安装教程及问题解决方法
2015/05/09 Python
python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序
2020/07/20 Python
python批量查询、汉字去重处理CSV文件
2018/05/31 Python
Python程序打包工具py2exe和PyInstaller详解
2019/06/28 Python
Django上使用数据可视化利器Bokeh解析
2019/07/31 Python
解决Tensorflow 内存泄露问题
2020/02/05 Python
新东方旗下远程教育网站:新东方在线
2020/03/19 全球购物
化学专业毕业生自荐信
2013/11/15 职场文书
银行见习期自我鉴定
2014/01/29 职场文书
小学信息技术教学反思
2014/02/10 职场文书
老同学聚会感言
2014/02/23 职场文书
2014年清明节网上祭英烈寄语
2014/04/09 职场文书
工伤事故赔偿协议书范文
2014/09/24 职场文书
2014年煤矿工人工作总结
2014/12/08 职场文书
吴仁宝观后感
2015/06/09 职场文书
求职信:求职应该注意的问题
2019/04/24 职场文书
最新最全的手机号验证正则表达式
2022/02/24 Javascript