JsonUtil.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <?php
  2. namespace loyalsoft;
  3. /**
  4. * Json转换工具,兼容UTF8格式
  5. * @author gwang
  6. * @version: <br/>
  7. * v1.3.0 优化decode方法, 检查是否json是合法json的同时, 将结果传递出来.
  8. * 去掉没有用到 json_last_error_msg()函数.
  9. * 去掉preg_replace的e参数用法, 完全使用preg_replace_callback.
  10. * 将v1.1.0中的改动移动到独立的方法中, 不干扰decode方法了.
  11. * gwang 2016.4.28 <br/>
  12. * v1.1.0 (未完成测试)在json_decode中集成反序列化的功能.如果参数中给出了目标类型/对象,
  13. * 则返回目标类型的实例. Ps.数据还不能处理 gwang 2017.xx.xx <br/>
  14. * v1.0.2 encode时增加判断,防止对string二次编码. gwang 2016.10.17 <br/>
  15. * v1.0.1 decode时加上了判断,如果不是json格式则返回原串. gwang 2016.4.28 <br/>
  16. * v1.0.0 file copy and created. gwang 2016.4.28 <br/>
  17. */
  18. class JsonUtil
  19. {
  20. /**
  21. * 对给定字符串尝试进行解析
  22. * @param string $string
  23. * @param mixed $obj (out) 解析出的对象
  24. * @return boolean 解析是否成功
  25. */
  26. private static function is_json($string, &$obj)
  27. {
  28. if (!is_string($string)) { # 不是字符串类型的对象
  29. return false;
  30. }
  31. if (!preg_match('/^[[|{]/', ltrim($string))) { # 字符串开头不是[或{ 则判定为非json格式
  32. // CLogUtil::debuglog('捕获不符合json格式的字符串' . $string);
  33. return false;
  34. }
  35. ob_start(); # 截获意外输出
  36. $obj = json_decode($string); # 解析json
  37. ob_end_clean(); # 抛弃输出
  38. return (json_last_error() == JSON_ERROR_NONE); # 返回
  39. }
  40. /**
  41. * 修正对字符串中中文的编码, Ps.(json_encode之后中文会转换为\u7956\u56fd形式的编码)
  42. * @param mixed $obj
  43. * @return string
  44. */
  45. public static function encode($obj)
  46. {
  47. $json = is_string($obj) ? $obj : json_encode($obj); # 防止对字符串二次编码
  48. if ($GLOBALS['OS'] == "linux") { # 还原中文字符串
  49. return preg_replace_callback('#\\\u([0-9a-f]{4})#i', function ($matches) {
  50. return iconv('UCS-2LE', 'UTF-8', pack('H4', $matches[1]));
  51. }, $json);
  52. } else if ($GLOBALS['OS'] == "win32") { # 还原中文字符串
  53. return preg_replace_callback('#\\\u([0-9a-f]{4})#i', function ($matches) {
  54. return iconv('UCS-2BE', 'UTF-8', pack('H4', $matches[1]));
  55. }, $json);
  56. }
  57. return $json;
  58. }
  59. /**
  60. * 对于异常的参数,记录到日志
  61. * @param type $string
  62. * @return obj
  63. */
  64. public static function decode($string)
  65. {
  66. $obj = $string;
  67. if (!self::is_json($string, $obj)) {
  68. // CLogUtil_HP::log("decoding: " . gettype($string) . " " # json解析失败,记录日志
  69. // . substr(var_export($string, true), 0, 30) . '...', "JsonUtil");
  70. // CLogUtil_HP::log(DebugHelper::get_call_stack(), "JsonUtil");
  71. }
  72. return $obj;
  73. }
  74. /**
  75. * 研发中..., 想着直接一步到位, 反序列化成目标类型的对象. -by gwang 2017年8月8日 09:49:09
  76. * @param string $str json字符串
  77. * @param mixed $tarType 目标类型
  78. * @return obj
  79. */
  80. public static function decode2Object($str, $tarType = null)
  81. {
  82. $obj = self::decode($str);
  83. if ($tarType != null) {
  84. $c = 'stdClass';
  85. if (is_string($tarType)) { # 类型名称
  86. $c = $tarType;
  87. } else if (is_object($tarType)) { # 目标类型的对象,数据还不能处理
  88. $c = get_class($tarType);
  89. }
  90. $desObj = new $c;
  91. CommUtil::loadObject($obj, $desObj); # 装到目标类型的箱子中
  92. $obj = $desObj;
  93. }
  94. return $obj;
  95. }
  96. }