Overview

Packages

  • Components
  • Internals
    • AR
  • RestApi
    • Objects
    • Services

Classes

  • CBHttpRequest
  • CBJson
  • CBJsonController
  • CBJsonInlineAction
  • CBJsonModel
  • Overview
  • Package
  • Class
  • Tree
  • Todo
  1: <?php
  2: /**
  3:  * Json helper functions.
  4:  *
  5:  * Adds the following functionality:
  6:  * <ul>
  7:  * <li>JSON string validation: CBJson::isValid()</li>
  8:  * <li>JSON formatting/indentation: CBJson::indent()</li>
  9:  * <li>JSON soft decoding: CBJson::softDecode*() (<i>does not fail if json is invalid</i>)</li>
 10:  * </ul>
 11:  *
 12:  * @since 1.0
 13:  * @package Components
 14:  * @author Konstantinos Filios <konfilios@gmail.com>
 15:  */
 16: class CBJson
 17: {
 18: 
 19:     /**
 20:      * Check if passed string is valid json.
 21:      *
 22:      * @param string $json Json string.
 23:      *
 24:      * @return boolean True if passed $json is valid
 25:      */
 26:     static public function isValid($json)
 27:     {
 28:         return is_string($json) && (json_decode($json) != null);
 29:     }
 30: 
 31:     /**
 32:      * Indent passed $json string to increase human-readability.
 33:      *
 34:      * @see http://recursive-design.com/blog/2008/03/11/format-json-with-php/
 35:      *
 36:      * @param string $json      Unformatted json.
 37:      * @param string $indentStr Indentation string (tabulator).
 38:      * @param string $newLine   Line terminator.
 39:      *
 40:      * @return string
 41:      */
 42:     static public function indent($json, $indentStr = '   ', $newLine = "\n")
 43:     {
 44: 
 45:         $result = '';
 46:         $pos = 0;
 47:         $strLen = strlen($json);
 48:         $prevChar = '';
 49:         $outOfQuotes = true;
 50: 
 51:         for ($i = 0; $i <= $strLen; $i++) {
 52: 
 53:             // Grab the next character in the string.
 54:             $char = substr($json, $i, 1);
 55: 
 56:             // Are we inside a quoted string?
 57:             if ($char == '"' && $prevChar != '\\') {
 58:                 $outOfQuotes = !$outOfQuotes;
 59: 
 60:                 // If this character is the end of an element,
 61:                 // output a new line and indent the next line.
 62:             } else if (($char == '}' || $char == ']') && $outOfQuotes) {
 63:                 $result .= $newLine;
 64:                 $pos--;
 65:                 for ($j = 0; $j < $pos; $j++) {
 66:                     $result .= $indentStr;
 67:                 }
 68:             }
 69: 
 70:             // Add the character to the result string.
 71:             $result .= $char;
 72: 
 73:             // If the last character was the beginning of an element,
 74:             // output a new line and indent the next line.
 75:             if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) {
 76:                 $result .= $newLine;
 77:                 if ($char == '{' || $char == '[') {
 78:                     $pos++;
 79:                 }
 80: 
 81:                 for ($j = 0; $j < $pos; $j++) {
 82:                     $result .= $indentStr;
 83:                 }
 84:             }
 85: 
 86:             $prevChar = $char;
 87:         }
 88: 
 89:         return $result;
 90:     }
 91: 
 92:     /**
 93:      * Returns string/text describing the last error occured while json encoding/decoding.
 94:      *
 95:      * This is supported only for php 5.3 or later.
 96:      *
 97:      * @see http://www.php.net/manual/en/function.json-last-error.php
 98:      *
 99:      * @return string
100:      */
101:     static public function getLastErrorString()
102:     {
103:         if (function_exists('json_last_error')) {
104:             $errorCode = json_last_error();
105: 
106:             switch ($errorCode) {
107:                 case JSON_ERROR_NONE:
108:                     return false;
109:                 case JSON_ERROR_DEPTH:
110:                     return 'Maximum stack depth exceeded';
111:                 case JSON_ERROR_STATE_MISMATCH:
112:                     return 'Invalid or malformed JSON';
113:                 case JSON_ERROR_CTRL_CHAR:
114:                     return 'Control character error, possibly incorrectly encoded';
115:                 case JSON_ERROR_SYNTAX:
116:                     return 'Syntax error';
117:                 case JSON_ERROR_UTF8:
118:                     return 'Malformed UTF-8 characters, possibly incorrectly encoded';
119:                 default:
120:                     return 'Unsupported error code '.$errorCode;
121:             }
122:         } else {
123:             return false;
124:             //      $error = error_get_last();
125:             //      if (empty($error) || empty($error['message'])) {
126:             //          return false;
127:             //      }
128:             //      return $error['message'];
129:         }
130:     }
131: 
132:     /**
133:      * Try to json-decode input.
134:      *
135:      * @param string $jsonInput
136:      * @return mixed
137:      */
138:     static public function softDecode($jsonInput)
139:     {
140:         try {
141:             $jsonOutput = self::decodeAssoc($jsonInput);
142:         } catch (Exception $e) {
143:             // Could not json decode, retain value
144:             $jsonOutput = $jsonInput;
145:         }
146: 
147:         return $jsonOutput;
148:     }
149: 
150:     /**
151:      * Try to json-decode array elements.
152:      *
153:      * If elements are not json-decoded their original values are retained.
154:      *
155:      * @param array $jsonInputs
156:      * @return array
157:      */
158:     static public function softDecodeArray(array $jsonInputs)
159:     {
160:         $jsonOutputs = array();
161:         foreach ($jsonInputs as $key=>$jsonInput) {
162:             $jsonOutputs[$key] = (is_array($jsonInput) || is_object($jsonInput))
163:                 ? self::softDecodeArray($jsonInput)
164:                 : self::softDecode($jsonInput);
165:         }
166:         return $jsonOutputs;
167:     }
168: 
169:     /**
170:      * Decode json input.
171:      *
172:      * @param string $jsonInput
173:      * @return mixed
174:      * @throws CException
175:      */
176:     static public function decodeAssoc($jsonInput)
177:     {
178:         // Object is optional
179:         if (empty($jsonInput)) {
180:             // Input string is empty, nothing to json-decode
181:             return null;
182:         }
183: 
184:         // Decode the object into an array
185:         $objectOutput = json_decode($jsonInput, true);
186: 
187:         if (($objectOutput === null) && ($jsonInput !== 'null')) {
188:             // Json_decode failed
189:             throw new CException('Could not JSON-decode input object');
190:         }
191: 
192:         return $objectOutput;
193:     }
194: }
195: 
Bogo Yii Json Service API documentation generated by ApiGen 2.8.0