function JSONEncodedToArray($JSONEncoded) {
//do nothing if not serializable
if (strlen($JSONEncoded) < 7)
{
throw new JSONException("It is not possible to decode a JSON content that doesn't contains at least 7 characters", -2);
}
//the shortening process result
$shortenedJSON = $JSONEncoded;
//short the JSON string to obtain maximum speed at the decode stage
$replaceTimes = 1;
while ($replaceTimes != 0)
{ $shortenedJSON = str_replace(" ", " ", $shortenedJSON, $replaceTimes); }
$replaceTimes = 1;
while ($replaceTimes != 0)
{ $shortenedJSON = str_replace("\n", "", $shortenedJSON, $replaceTimes); }
$replaceTimes = 1;
while ($replaceTimes != 0)
{ $shortenedJSON = str_replace("\t", "", $shortenedJSON, $replaceTimes); }
$JSONIsCleanAndReady = FALSE;
while (!$JSONIsCleanAndReady) {
$JSONIsCleanAndReady = TRUE;
//delete the starting space
if ($shortenedJSON[0] == ' ') {
$shortenedJSON = substr($shortenedJSON, 1);
$JSONIsCleanAndReady = FALSE;
}
//delete the final space
$shortenedJSONLength = strlen($shortenedJSON);
if ($shortenedJSON[$shortenedJSONLength - 1] == ' ') {
$shortenedJSON = substr($shortenedJSON, 0, $shortenedJSONLength - 1);
$JSONIsCleanAndReady = FALSE;
}
//delete the beginning {
if ($shortenedJSON[0] == '{') {
$shortenedJSON = substr($shortenedJSON, 1);
$JSONIsCleanAndReady = FALSE;
}
//delete the final }
$shortenedJSONLength = strlen($shortenedJSON);
if ($shortenedJSON[$shortenedJSONLength - 1] == '}') {
$shortenedJSON = substr($shortenedJSON, 0, $shortenedJSONLength - 1);
$JSONIsCleanAndReady = FALSE;
}
}
//split the shortened string into characters
$JSONChars = str_split($shortenedJSON);
$JSONCharsNumber = count($JSONChars);
$endOfJSONObject = FALSE;
//setup an empty array
$resultingArray = array();
//what is the cycle currently parsing?
/* $parsing Value | meaning
* 0 | nothing
* 1 | name
* 2 | value
* 3 | aftername
*/
$parsing = 0;
//the last parsed property name
$lastPropertyNameParsed = "";
//the last parsed property value
$lastPropertyValueParsed = "";
//the last parsed property type
/* $lastPropertyValueParsedType Value | meaning
* 0 | null
* 1 | string
* 2 | number
* 3 | object
* 4 | boolean
*/
$lastPropertyValueParsedType = -1;
//used to read JSON objects inside other objects
$parenthesis = 0;
$lastSaved = FALSE;
//cycle each character starting from the first one
reset($JSONChars);
for ($i = 0; $i < $JSONCharsNumber; $i++)
{
//get the current character
$currentCharacter = current($JSONChars);
if ((($currentCharacter == ' ') && ($lastPropertyValueParsedType == 1) && ($parsing == 2)) || (($currentCharacter == ' ') && ($lastPropertyValueParsedType == 3) && ($parsing == 2)) || ($currentCharacter != ' ') || (($currentCharacter == ' ') && ($parsing == 1)) || (($currentCharacter == ',') && ($parsing != 0)))
{
if ($parsing == 0)
{
if ($currentCharacter != '"')
{
throw new JSONException("Unexpected character '".$currentCharacter."', expected character '\"' instead", -6);
} else {
$parsing = 1;
$lastPropertyNameParsed = "";
}
} else if ($parsing == 1) {
if ($currentCharacter != '"')
{
$lastPropertyNameParsed = $lastPropertyNameParsed.$currentCharacter;
} else {
$parsing = 3;
$lastSaved = FALSE;
}
} else if ($parsing == 3) {
if ($currentCharacter != ':')
{ throw new JSONException("The JSON is not valid: unexpected character '".$currentCharacter."', after a json property name the ':' character is expected", -7); }
else
{ $parsing = 2; $lastPropertyValueParsed = ""; }
} else if ($parsing == 2) {
//get the json property value type
if ((strlen($lastPropertyValueParsed) == 0) && ($lastPropertyValueParsedType == -1)) {
if ($currentCharacter == "\"") {
$lastPropertyValueParsedType = 1;
$lastPropertyValueParsed = "";
} else if ($currentCharacter == 'n') {
$lastPropertyValueParsed = "n";
$lastPropertyValueParsedType = 0;
} else if (($currentCharacter == 't') || ($currentCharacter == 'f')) {
$lastPropertyValueParsed = "".$currentCharacter;
$lastPropertyValueParsedType = 4;
} else if (($currentCharacter == '0') || ($currentCharacter == '1') || ($currentCharacter == '2') || ($currentCharacter == '3') || ($currentCharacter == '4') || ($currentCharacter == '5') || ($currentCharacter == '6') || ($currentCharacter == '7') || ($currentCharacter == '8') || ($currentCharacter == '9')) {
$lastPropertyValueParsed = "".$currentCharacter;
$lastPropertyValueParsedType = 2;
} else if ($currentCharacter == '{') {
$lastPropertyValueParsed = "";
$lastPropertyValueParsedType = 3;
$parenthesis = 1;
} else {
throw new JSONException("Unrecognized JSON property type.", -8);
}
} else {
if ((($lastPropertyValueParsedType != 1) && ($lastPropertyValueParsedType != 3)) && ($currentCharacter == ',')) {
//end of number, boolean or null parsing
$parsing = 0;
} else if (($lastPropertyValueParsedType == 1) && ($currentCharacter == '"')) {
//end of string parsing
$parsing = 0;
while ((current($JSONChars) != ",") && ($i < $JSONCharsNumber)) {
next($JSONChars);
$i++;
}
} else {
if ($lastPropertyValueParsedType == 3)
{
//watch out for parenthesis
if ($currentCharacter == '{')
$parenthesis++;
else if ($currentCharacter == '}')
$parenthesis--;
if ($parenthesis == 0)
{
$endOfJSONObject = TRUE;
//end of object parsing
$parsing = 0;
}
}
//store the last character
if (!$endOfJSONObject)
$lastPropertyValueParsed = $lastPropertyValueParsed.$currentCharacter;
$endOfJSONObject = FALSE;
}
if ($parsing == 0) {
$lastSaved = TRUE;
if ($lastPropertyValueParsedType == 1)
{
$resultingArray[$lastPropertyNameParsed] = $lastPropertyValueParsed;
}
else if ($lastPropertyValueParsedType == 0)
{
if ($lastPropertyValueParsed == "null")
$resultingArray[$lastPropertyNameParsed] = NULL;
else
throw new JSONException("Unrecognized JSON value, expected \"null\", found \"".$lastPropertyValueParsed."\"", -9);
}
else if ($lastPropertyValueParsedType == 2)
{
if (is_numeric($lastPropertyValueParsedType)) {
if (strpos($lastPropertyValueParsed, '.') == FALSE)
$resultingArray[$lastPropertyNameParsed] = intval($lastPropertyValueParsed);
else
$resultingArray[$lastPropertyNameParsed] = floatval($lastPropertyValueParsed);
} else {
throw new JSONException("Invalid representation of a number", -10);
}
}
else if ($lastPropertyValueParsedType == 3)
{
$resultingArray[$lastPropertyNameParsed] = $this->JSONEncodedToArray($lastPropertyValueParsed);
}
else if ($lastPropertyValueParsedType == 4)
{
if ($lastPropertyValueParsed == "true") {
$resultingArray[$lastPropertyNameParsed] = TRUE;
} else if ($lastPropertyValueParsed == "false") {
$resultingArray[$lastPropertyNameParsed] = FALSE;
} else {
throw new JSONException("Unexpected JSON value: true or false expected, ".$lastPropertyValueParsed." found", -9);
}
}
$lastPropertyValueParsedType = -1;
}
}
}
}
//jump to the next character
next($JSONChars);
}
if (!$lastSaved) {
if ($lastPropertyValueParsedType == 1)
{
$resultingArray[$lastPropertyNameParsed] = $lastPropertyValueParsed;
}
else if ($lastPropertyValueParsedType == 0)
{
if ($lastPropertyValueParsed == "null")
$resultingArray[$lastPropertyNameParsed] = NULL;
else
throw new JSONException("Unrecognized JSON value, expected \"null\", found \"".$lastPropertyValueParsed."\"", -9);
}
else if ($lastPropertyValueParsedType == 2)
{
if (is_numeric($lastPropertyValueParsedType)) {
if (strpos($lastPropertyValueParsed, '.') == FALSE)
$resultingArray[$lastPropertyNameParsed] = intval($lastPropertyValueParsed);
else
$resultingArray[$lastPropertyNameParsed] = floatval($lastPropertyValueParsed);
} else {
throw new JSONException("Invalid representation of a number", -10);
}
}
else if ($lastPropertyValueParsedType == 3)
{
$resultingArray[$lastPropertyNameParsed] = $this->JSONEncodedToArray($lastPropertyValueParsed);
}
else if ($lastPropertyValueParsedType == 4)
{
if ($lastPropertyValueParsed == "true") {
$resultingArray[$lastPropertyNameParsed] = TRUE;
} else if ($lastPropertyValueParsed == "false") {
$resultingArray[$lastPropertyNameParsed] = FALSE;
} else {
throw new JSONException("Unexpected JSON value: true or false expected, ".$lastPropertyValueParsed." found", -9);
}
}
$lastPropertyValueParsedType = -1;
}
//return the given array
return $resultingArray;
}