Object_ext.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. <?php
  2. namespace loyalsoft;
  3. /**
  4. * 扩展对象的一些通用方法
  5. * 使用方法: $var = new XX($obj); ... 用完后注意进行回存.(相当于克隆一个原始对象,若需覆盖原始对象记得回存操作)
  6. * @version
  7. * 1.0.3 增加了Json()和MD5()方法,用于计算对象的摘要,方便与客户端或者存储端进行校验. --gwang 2022.5.31
  8. * 1.0.2 增加了LoadFrom()方法. --gwang 2020.4.24
  9. * 1.0.1 改名, PHP 7以后的语法中已经将Object作为关键字 --gwang 2017年8月2日
  10. * 1.0.0 Created at 2017-3-28. by --gwang
  11. * @author gwang (mail@wanggangzero.cn)
  12. * @copyright ? 2017-3-28, SJZ LoyalSoft Corporation & gwang. All rights reserved.
  13. */
  14. class Object_ext {
  15. /**
  16. * 默认构造函数,能够智能提取关联数组或者是object中的字段进行初始化.
  17. * Ps. 不会进行递归类型检查, php的serilize函数也没有附带字段的类型信息
  18. */
  19. function __construct($arg = null) {
  20. if (func_num_args() != 1 || is_null($arg)) { # 若参数为null,无特殊操作
  21. return;
  22. }
  23. $para = is_array($arg) ? $arg : (array) $arg; # 关联数组
  24. $vars = get_class_vars(get_class($this)); # 后期绑定,获得实例的实际类名称=>属性数组
  25. foreach ($vars as $name => $value) {
  26. $this->$name = isset($para[$name]) ? $para[$name] : $value; # 取参数中的或者默认值
  27. }
  28. }
  29. /**
  30. * 从对象加载数据(赋值给自己的字段)
  31. * (注意: 对于自身未定义的字段直接抛弃了,所以要求所有字段都必须在model中定义好,运行时增加的字段下次加载时就会丢失)
  32. * @param array/Object $obj
  33. */
  34. public function LoadFrom($obj) {
  35. if (func_num_args() != 1 || is_null($obj)) { # 防御: 参数数量不对
  36. die("too many args or arg obj was null!");
  37. }
  38. $para = is_array($obj) ? $obj : (array) $obj; # 转关联数组
  39. $vars = get_class_vars(get_class($this)); # 后期绑定,获得实例的实际类名称=>属性数组
  40. foreach ($vars as $name => $value) {
  41. if (isset($para[$name])) {
  42. $this->$name = $para[$name]; # 取参数中的或者默认值
  43. }
  44. }
  45. return $this;
  46. }
  47. public function __toString() { # 用json_encode覆盖下toString()方法
  48. return $this->toString();
  49. }
  50. /**
  51. * @return 将自身数据序列化为json串.
  52. */
  53. public function Json() {
  54. return JsonUtil::encode($this);
  55. }
  56. public function toString() { # 还没想好要不要留一个显式的toString()方法
  57. $str = $this->Json();
  58. return $str;
  59. }
  60. /**
  61. * @param bool $lower 是否返回小写字符串,默认值false, 返回大写字符串
  62. * @return string 计算自身数据序列化为json串后的MD5值(大写16进制)
  63. */
  64. public function MD5($lower = false) {
  65. $str = $this->Json();
  66. return $lower ? md5($str) : strtoupper(md5($str));
  67. }
  68. /**
  69. * 从json反序列化回来的时候,修正下类型. 有的时候空数组会序列化为{},再反序列化回来的时候类型就变了.
  70. */
  71. public function fixArray() {
  72. $ref = new \ReflectionObject($this); # 建立反射对象
  73. $properties = $ref->getProperties(); # 获取属性列表
  74. foreach ($properties as $p) { # 遍历属性
  75. isEditor() and $p = new \ReflectionProperty();
  76. $attrs = $p->getAttributes("loyalsoft\ArrayType"); # 获取 "数组类型" 的注解
  77. if (count($attrs) > 0) {
  78. $v = self::ConsureArr($p->getValue($this)); # 属性值类型转换为数组
  79. $p->setValue($this, $v); # 回写属性值到对象上
  80. }
  81. }
  82. }
  83. private static function ConsureArr($mix) {
  84. if (is_array($mix)) {
  85. return $mix;
  86. }
  87. return (array) $mix;
  88. }
  89. }