JsonHelper::decode() 

\nn\t3::JsonHelper()->decode($str, $useArray = true); 

Converts a JS object string into an array.

$data = \Nng\Nnhelpers\Helpers\JsonHelper::decode( "{title:'Test', cat:[2,3,4]}" );
print_r($data);
Copied!

The PHP function json_decode() only works with JSON syntax: {"key": "value"}. Neither line breaks nor comments are allowed in JSON. This function can also be used to parse strings in JavaScript notation.

| @return array|string

Source Code 

public static function decode($str, $useArray=true)
{
	$str = trim($str);
	if(function_exists('json_decode'))
	{
		$json = json_decode($str,$useArray);
		if($json !== null)
			return $json;
	}
	$str = self::reduceString($str);
	switch (strtolower($str)) {
		case 'true':
			return true;
		case 'false':
			return false;
		case 'null':
			return null;
		default:
			if (is_numeric($str)) {
				// Lookie-loo, it's a number
				// This would work on its own, but I'm trying to be
				// good about returning integers where appropriate:
				// return (float)$str;
				// Return float or int, as appropriate
				return ((float)$str == (integer)$str)
					? (integer)$str
					: (float)$str;
			} elseif (preg_match('/^("|\').+(\1)$/s', $str, $m) && $m[1] == $m[2]) {
				// STRINGS RETURNED IN UTF-8 FORMAT
				$delim = substr($str, 0, 1);
				$chrs = substr($str, 1, -1);
				$utf8 = '';
				$strlen_chrs = strlen($chrs);
				for ($c = 0; $c < $strlen_chrs; ++$c) {
					$substr_chrs_c_2 = substr($chrs, $c, 2);
					$ord_chrs_c = ord($chrs[$c]);
					switch (true) {
						case $substr_chrs_c_2 == '\b':
							$utf8 .= chr(0x08);
							++$c;
							break;
						case $substr_chrs_c_2 == '\t':
							$utf8 .= chr(0x09);
							++$c;
							break;
						case $substr_chrs_c_2 == '\n':
							$utf8 .= chr(0x0A);
							++$c;
							break;
						case $substr_chrs_c_2 == '\f':
							$utf8 .= chr(0x0C);
							++$c;
							break;
						case $substr_chrs_c_2 == '\r':
							$utf8 .= chr(0x0D);
							++$c;
							break;
						case $substr_chrs_c_2 == '\\"':
						case $substr_chrs_c_2 == '\\\'':
						case $substr_chrs_c_2 == '\\\\':
						case $substr_chrs_c_2 == '\\/':
							if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
							   ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
								$utf8 .= $chrs[++$c];
							}
							break;
						case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
							// single, escaped unicode character
							$utf16 = chr(hexdec(substr($chrs, ($c+2), 2)))
								   . chr(hexdec(substr($chrs, ($c+4), 2)));
							$utf8 .= self::utf16beToUTF8($utf16);
							$c+=5;
							break;
						case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
							$utf8 .= $chrs[$c];
							break;
						case ($ord_chrs_c & 0xE0) == 0xC0:
							// characters U-00000080 - U-000007FF, mask 110XXXXX
							//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
							$utf8 .= substr($chrs, $c, 2);
							++$c;
							break;
						case ($ord_chrs_c & 0xF0) == 0xE0:
							// characters U-00000800 - U-0000FFFF, mask 1110XXXX
							// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
							$utf8 .= substr($chrs, $c, 3);
							$c += 2;
							break;
						case ($ord_chrs_c & 0xF8) == 0xF0:
							// characters U-00010000 - U-001FFFFF, mask 11110XXX
							// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
							$utf8 .= substr($chrs, $c, 4);
							$c += 3;
							break;
						case ($ord_chrs_c & 0xFC) == 0xF8:
							// characters U-00200000 - U-03FFFFFF, mask 111110XX
							// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
							$utf8 .= substr($chrs, $c, 5);
							$c += 4;
							break;
						case ($ord_chrs_c & 0xFE) == 0xFC:
							// characters U-04000000 - U-7FFFFFFF, mask 1111110X
							// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
							$utf8 .= substr($chrs, $c, 6);
							$c += 5;
							break;
					}
				}
				return $utf8;
			} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
				// array, or object notation
				if ($str[0] == '[') {
					$stk = array(self::JSON_IN_ARR);
					$arr = array();
				} else {
					if ($useArray) {
						$stk = array(self::JSON_IN_OBJ);
						$obj = array();
					} else {
						$stk = array(self::JSON_IN_OBJ);
						$obj = new stdClass();
					}
				}
				$stk[] = array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false);
				$chrs = substr($str, 1, -1);
				$chrs = self::reduceString($chrs);
				if ($chrs == '') {
					if (reset($stk) == self::JSON_IN_ARR) {
						return $arr;
					} else {
						return $obj;
					}
				}
				//print("\nparsing [$chrs}\n");
				$strlen_chrs = strlen($chrs);
				for ($c = 0; $c <= $strlen_chrs; ++$c) {
					$top = end($stk);
					$substr_chrs_c_2 = substr($chrs, $c, 2);
					if (($c == $strlen_chrs) || (($chrs[$c] == ',') && ($top['what'] == self::JSON_SLICE))) {
						// found a comma that is not inside a string, array, etc.,
						// OR we've reached the end of the character list
						$slice = substr($chrs, $top['where'], ($c - $top['where']));
						$stk[] = array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false);
						//print("Found split at [$c]: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
						if (reset($stk) == self::JSON_IN_ARR) {
							// we are in an array, so just push an element onto the stack
							$val = self::decode($slice,$useArray);
							if (is_string($val)) $val = html_entity_decode($val);
							$arr[] = $val;
						} elseif (reset($stk) == self::JSON_IN_OBJ) {
							// we are in an object, so figure
							// out the property name and set an
							// element in an associative array,
							// for now
							if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
								// "name":value pair
								$key = self::decode($parts[1],$useArray);
								$val = self::decode($parts[2],$useArray);
								if (is_string($val)) $val = html_entity_decode($val);
								if ($useArray) {
									$obj[$key] = $val;
								} else {
									$obj->$key = $val;
								}
							} elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
								// name:value pair, where name is unquoted
								$key = $parts[1];
								$val = self::decode($parts[2],$useArray);
								if (is_string($val)) $val = html_entity_decode($val);
								if ($useArray) {
									$obj[$key] = $val;
								} else {
									$obj->$key = $val;
								}
							}
						}
					} elseif ((($chrs[$c] == '"') || ($chrs[$c] == "'")) && ($top['what'] != self::JSON_IN_STR)) {
						// found a quote, and we are not inside a string
						$stk[] = array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs[$c]);
						//print("Found start of string at [$c]\n");
					} elseif (($chrs[$c] == $top['delim']) &&
							 ($top['what'] == self::JSON_IN_STR) &&
							 (($chrs[$c - 1] != "\\") ||
							 ($chrs[$c - 1] == "\\" && $chrs[$c - 2] == "\\"))) {
						// found a quote, we're in a string, and it's not escaped
						array_pop($stk);
						//print("Found end of string at [$c]: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
					} elseif (($chrs[$c] == '[') &&
							 in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) {
						// found a left-bracket, and we are in an array, object, or slice
						$stk[] = array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false);
						//print("Found start of array at [$c]\n");
					} elseif (($chrs[$c] == ']') && ($top['what'] == self::JSON_IN_ARR)) {
						// found a right-bracket, and we're in an array
						array_pop($stk);
						//print("Found end of array at [$c]: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
					} elseif (($chrs[$c] == '{') &&
							 in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) {
						// found a left-brace, and we are in an array, object, or slice
						$stk[] = array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false);
						//print("Found start of object at [$c]\n");
					} elseif (($chrs[$c] == '}') && ($top['what'] == self::JSON_IN_OBJ)) {
						// found a right-brace, and we're in an object
						array_pop($stk);
						//print("Found end of object at [$c]: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
					} elseif (($substr_chrs_c_2 == '/*') &&
							 in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) {
						// found a comment start, and we are in an array, object, or slice
						$stk[] = array('what' => self::JSON_IN_CMT, 'where' => $c, 'delim' => false);
						$c++;
						//print("Found start of comment at [$c]\n");
					} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) {
						// found a comment end, and we're in one now
						array_pop($stk);
						$c++;
						for ($i = $top['where']; $i <= $c; ++$i)
							$chrs = substr_replace($chrs, ' ', $i, 1);
						//print("Found end of comment at [$c]: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
					}
				}
				if (reset($stk) == self::JSON_IN_ARR) {
					return $arr;
				} elseif (reset($stk) == self::JSON_IN_OBJ) {
					return $obj;
				}
			}
	}
}
Copied!