Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

119 lines
4.2KB

  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\helpers;
  8. use yii\base\InvalidParamException;
  9. use yii\base\Arrayable;
  10. use yii\web\JsExpression;
  11. /**
  12. * BaseJson provides concrete implementation for [[Json]].
  13. *
  14. * Do not use BaseJson. Use [[Json]] instead.
  15. *
  16. * @author Qiang Xue <qiang.xue@gmail.com>
  17. * @since 2.0
  18. */
  19. class BaseJson
  20. {
  21. /**
  22. * Encodes the given value into a JSON string.
  23. * The method enhances `json_encode()` by supporting JavaScript expressions.
  24. * In particular, the method will not encode a JavaScript expression that is
  25. * represented in terms of a [[JsExpression]] object.
  26. * @param mixed $value the data to be encoded
  27. * @param integer $options the encoding options. For more details please refer to
  28. * <http://www.php.net/manual/en/function.json-encode.php>. Default is `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE`.
  29. * @return string the encoding result
  30. */
  31. public static function encode($value, $options = 320)
  32. {
  33. $expressions = [];
  34. $value = static::processData($value, $expressions, uniqid());
  35. $json = json_encode($value, $options);
  36. return empty($expressions) ? $json : strtr($json, $expressions);
  37. }
  38. /**
  39. * Decodes the given JSON string into a PHP data structure.
  40. * @param string $json the JSON string to be decoded
  41. * @param boolean $asArray whether to return objects in terms of associative arrays.
  42. * @return mixed the PHP data
  43. * @throws InvalidParamException if there is any decoding error
  44. */
  45. public static function decode($json, $asArray = true)
  46. {
  47. if (is_array($json)) {
  48. throw new InvalidParamException('Invalid JSON data.');
  49. }
  50. $decode = json_decode((string) $json, $asArray);
  51. switch (json_last_error()) {
  52. case JSON_ERROR_NONE:
  53. break;
  54. case JSON_ERROR_DEPTH:
  55. throw new InvalidParamException('The maximum stack depth has been exceeded.');
  56. case JSON_ERROR_CTRL_CHAR:
  57. throw new InvalidParamException('Control character error, possibly incorrectly encoded.');
  58. case JSON_ERROR_SYNTAX:
  59. throw new InvalidParamException('Syntax error.');
  60. case JSON_ERROR_STATE_MISMATCH:
  61. throw new InvalidParamException('Invalid or malformed JSON.');
  62. case JSON_ERROR_UTF8:
  63. throw new InvalidParamException('Malformed UTF-8 characters, possibly incorrectly encoded.');
  64. default:
  65. throw new InvalidParamException('Unknown JSON decoding error.');
  66. }
  67. return $decode;
  68. }
  69. /**
  70. * Pre-processes the data before sending it to `json_encode()`.
  71. * @param mixed $data the data to be processed
  72. * @param array $expressions collection of JavaScript expressions
  73. * @param string $expPrefix a prefix internally used to handle JS expressions
  74. * @return mixed the processed data
  75. */
  76. protected static function processData($data, &$expressions, $expPrefix)
  77. {
  78. if (is_object($data)) {
  79. if ($data instanceof JsExpression) {
  80. $token = "!{[$expPrefix=" . count($expressions) . ']}!';
  81. $expressions['"' . $token . '"'] = $data->expression;
  82. return $token;
  83. } elseif ($data instanceof \JsonSerializable) {
  84. $data = $data->jsonSerialize();
  85. } elseif ($data instanceof Arrayable) {
  86. $data = $data->toArray();
  87. } else {
  88. $result = [];
  89. foreach ($data as $name => $value) {
  90. $result[$name] = $value;
  91. }
  92. $data = $result;
  93. }
  94. if ($data === []) {
  95. return new \stdClass();
  96. }
  97. }
  98. if (is_array($data)) {
  99. foreach ($data as $key => $value) {
  100. if (is_array($value) || is_object($value)) {
  101. $data[$key] = static::processData($value, $expressions, $expPrefix);
  102. }
  103. }
  104. }
  105. return $data;
  106. }
  107. }