作为一名深度 phper, 我如果要黑咱们 PHP, 就像说自己母校差一样, 大家不要见外.
个人博客地址: https://mengkang.net/1368.html
故事的开始
这几天观察错误日志发现有一个数据反序列化的 notice 错误, 实际情况我是从缓存中读取数据然后反序列化, 因为反序列化失败, 所以实际每次都是去数据库取的值. 背后性能影响还是挺大的.
缺失的异常
刚开始写代码的时候一直不明白为什么要用异常, 感觉 if else 就能搞定了, 为什么还要多此一举, 现在反而觉得 PHP 的异常太少.
对比两种序列化场景, 一个是 JSON, 另一个是 serialize.
JSON
在 JSON encode/decode 的时候, 如果出现异常, 可以通过 json_last_error() 来获取.
这样的设计只能说勉强够用, 不太符合面向对象的套路.
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 代码更加健壮, 安全. 也希望大家不要只看到 PHP 干活快, 快的背后隐藏着无数的潜在风险, PHP 虽好, 但是也不能贪杯哦.
来源: https://segmentfault.com/a/1190000019528833