Dashboard sipadu mbip
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

JsonRef.php 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <?php
  2. /* Copyright (c) 2014-2019 Geert Bergman (geert@scrivo.nl), highlight.php
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * 1. Redistributions of source code must retain the above copyright notice,
  8. * this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright notice,
  10. * this list of conditions and the following disclaimer in the documentation
  11. * and/or other materials provided with the distribution.
  12. * 3. Neither the name of "highlight.js", "highlight.php", nor the names of its
  13. * contributors may be used to endorse or promote products derived from this
  14. * software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  20. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  21. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  22. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  23. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  24. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  25. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  26. * POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. /**
  29. * Implementation of the \Highlight\JsonRef class.
  30. */
  31. namespace Highlight;
  32. /**
  33. * Class to decode JSON data that contains path-based references.
  34. *
  35. * The language data file for highlight.js are written as JavaScript classes
  36. * and therefore may contain variables. This allows for inner references in
  37. * the language data. This kind of data can be converterd to JSON using the
  38. * path based references. This class can be used to decode such JSON
  39. * structures. It follows the conventions for path based referencing as
  40. * used in dojox.json.ref form the Dojo toolkit (Javascript). A typical
  41. * example of such a structure is as follows:
  42. *
  43. * {
  44. * "name":"Kris Zyp",
  45. * "children":[{"name":"Jennika Zyp"},{"name":"Korban Zyp"}],
  46. * "spouse":{
  47. * "name":"Nicole Zyp",
  48. * "spouse":{"$ref":"#"},
  49. * "children":{"$ref":"#children"}
  50. * },
  51. * "oldestChild":{"$ref":"#children.0"}
  52. * }
  53. *
  54. * Usage example:
  55. *
  56. * $jr = new JsonRef();
  57. * $data = $jr->decode(file_get_contents("data.json"));
  58. * echo $data->spouse->spouse->name; // echos 'Kris Zyp'
  59. * echo $data->oldestChild->name; // echos 'Jennika Zyp'
  60. */
  61. class JsonRef
  62. {
  63. /**
  64. * Array to hold all data paths in the given JSON data.
  65. *
  66. * @var array
  67. */
  68. private $paths = null;
  69. /**
  70. * Recurse through the data tree and fill an array of paths that reference
  71. * the nodes in the decoded JSON data structure.
  72. *
  73. * @param mixed $s Decoded JSON data (decoded with json_decode)
  74. * @param string $r The current path key (for example: '#children.0').
  75. */
  76. private function getPaths(&$s, $r = "#")
  77. {
  78. $this->paths[$r] = &$s;
  79. if (is_array($s) || is_object($s)) {
  80. foreach ($s as $k => &$v) {
  81. if ($k !== "\$ref") {
  82. $this->getPaths($v, $r == "#" ? "#{$k}" : "{$r}.{$k}");
  83. }
  84. }
  85. }
  86. }
  87. /**
  88. * Recurse through the data tree and resolve all path references.
  89. *
  90. * @param mixed $s Decoded JSON data (decoded with json_decode)
  91. */
  92. private function resolvePathReferences(&$s, $limit = 20, $depth = 1)
  93. {
  94. if ($depth >= $limit) {
  95. return;
  96. }
  97. ++$depth;
  98. if (is_array($s) || is_object($s)) {
  99. foreach ($s as $k => &$v) {
  100. if ($k === "\$ref") {
  101. $s = $this->paths[$v];
  102. } else {
  103. $this->resolvePathReferences($v, $limit, $depth);
  104. }
  105. }
  106. }
  107. }
  108. /**
  109. * Decode JSON data that may contain path based references.
  110. *
  111. * @param string|object $json JSON data string or JSON data object
  112. *
  113. * @return mixed The decoded JSON data
  114. */
  115. public function decode($json)
  116. {
  117. // Clear the path array.
  118. $this->paths = array();
  119. // Decode the given JSON data if necessary.
  120. $x = is_string($json) ? json_decode($json) : $json;
  121. // Get all data paths.
  122. $this->getPaths($x);
  123. // Resolve all path references.
  124. $this->resolvePathReferences($x);
  125. // Return the data.
  126. return $x;
  127. }
  128. }