Remove quotes from json_encoded ints prior to 5.3.3 - php

When using json_encode, it annoyingly automatically coverts the int keys to strings. For example, if you have an array:
$a = array();
$a[12] = 15;
echo json_encode($a);
{"12":15} //notice the quotes around 12
After searching SO, the solution is to use
json_encode($array,JSON_NUMERIC_CHECK)
However, that is only available in php > 5.3.3. The production server I'm stuck with is using 5.3.2.
Surely there is a work around?

So the problem here is that you are basically mixing your approach to the data structure and json_encode() is trying to make a best guess as to how to interpret your array, since in JSON, there is not such concept of a non-zero based, numerically indexed array.
If for example, you had a zero-based numeric array with a continuous number sequence, json_encode() would encode this a a numerically-indexed array of the format:
[value1, value2, ...]
Since you don't have a zero-based array, your data structure is being interpreted as an object structure and given a string key (the only available key type for an object in JSON) of the format:
{"key", value}
So it seems you need to make up your mind as to what you are really trying to represent in your array. Do you only need a numerically based array, or do you need object encoding.

Related

Print value from stdClass Object/array with curly brackets

Using PHP, I printed out an array ($result) using print_r. But the format in which the array has been returned is a new one on me. Specifically, how do I retrieve the text found in the field "reviews_review" ("Wow, what a great...") when it's found in this particular format with its multiple values? Example:
stdClass Object
(
[node_reviews_nid] => 5270
[reviews_review] => a:2:{s:5:"value";s:38:"Wow, what a great place. The bestest!";s:6:"format";s:13:"filtered_html";}
Those extra values and curly brackets have got me stumped. If I wanted the node_reviews_nid I could simply use $result->node_reviews_nid" - but doing that to get reviews_review just retrieves too much ie,
a:2:{s:5:"value";s:38:"Wow, what a great place. The bestest!";s:6:"format";s:13:"filtered_html";})
The odd curly brackets you're seeing are the result of PHP's serialize function.
Basically it's intended to convert complex structures like objects, nested arrays and so on into simple strings which are easier and safer to transfer, for example over HTTP. Think of it as JSON representation, but specific to PHP (do not attempt to json_decode() a serialized value).
Also worth noting is that serialize-d string has a maximum length, beyond which it's simply truncated, so avoid using it for very large structures - you'll lose data.
The reverse of that is unserialize. So to read the review's text, you would first have to unserialize the "reviews_review" property, then reference the "value" index of the resulting array.
$review_data = unserialize($result->reviews_review);
$review_text = $review_data['value'];
print($review_text);
The data in reviews_review looks like a serialized array i.e. written using the serialize() function
So you will need to unserialize it using unserialize() before you can use it
$review = unserialize($obj->reviews_review);
print_r($review);

php json_encode() output changes based on the array indices

I was trying to get some values from MySQL database and when converting into JSON array using json_encode() I got a JSON object , after a while I found out that the indices was the root cause of the problem
here's the example I mentioned
<?php
$array = array(0=>"zero",2=>"two");
$another_array=array(0=>"zero",1=>"one");
print_r(json_encode($array)); // output: {"0":"zero","2":"two"}
print_r(json_encode($another_array)); //output: ["zero","one"]
?>
so what's the reason for that ?
Because array(0=>"zero",1=>"one") is the same as array("zero", "one") and the JSON encoder assumes the latter is a list (since that's how PHP does lists) and has no way to tell the former from the latter.
If you want to force json_encode to treat all arrays as objects, pass JSON_FORCE_OBJECT as the second argument:
json_encode(array(0=>"zero",1=>"one"), JSON_FORCE_OBJECT)
// {"0":"zero","1":"one"}
If you always want a json list instead, get rid of the keys (e.g. using array_values()) before encoding.

PHP multidimensional array to JSON

So im trying to figure out the best way to get MySql table data into either a multidimensional PHP array or convert that multidimensional array into a json string.
Essentially what im trying to do is have a php include that returns the JSON string so i can iterate through it. I am needing a single key with multiple values, so im not 100% sure that im headed in the right direction.
I want to assign multiple values to the same key, for example:
[{"key1": "package1", "package2", "package3"}, {"key2": "package1", "package2", "package3", "package4"}]
I think that is not going to work right? Because i dont have any type of index's?
That is not valid JSON. The structure you are looking for would be something like:
[
{"key1": ["package1", "package2", "package3"]},
{"key2": ["package1", "package2", "package3", "package4"}]
^ An array as the value to the key "key1", "key2", etc..
]
At the PHP side, you would need something like:
For every row fetched from MySQL
$arr[$key] = <new array>
for each package:
append package to $arr[$key]
echo out json_encode($arr)
JS arrays have an implicit array keying, starting at index 0. What you've got is a perfectly valid JS array, the equivalent of having written:
var x = []; // create new empty array
x[0] = {"key1": .... }; // first object
x[1] = {"key2": ....} // second object
Note that the contents of your {} sub-objects is NOT valid.
You should never EVER built a JSON string by hand. It's too unreliable and easy to mess up. It's just easier to use a native data structure (php arrays/objects), then json_encode() them. Ditto on the other end of the process - don't decode the string manually. Convert to a native data structure (e.g. json_decode(), JSON.parse()) and then deal with the native structure directly.
essentially, JSON is a transmission format, not a manipulation format.

JSON_ENCODE of multidimensional array giving different results

When doing a json_encode a multidimensional array in PHP, I'm noticing a different output simply by naming one of the arrays, as opposed to not naming them. For Example:
$arrytest = array(array('a'=>1, 'b'=>2),array('c'=>3),array('d'=>4));
json_encode($arrytest)
gives a single array of multiple json objects
[{"a":1,"b":2},{"c":3},{"d":4}];
whereas simply assigning a name to the middle array
$arrytest = array(array('a'=>1, 'b'=>2),"secondarray"=>array('c'=>3),array('d'=>4));
json_encode($arrytest)
creates a single json object with multiple json objects inside
{"0":{"a":1,"b":2},"secondarray":{"c":3},"1":{"d":4}};
why would the 1st option not return the same reasults as the 2nd execpt with "1" in place of "secondarray"
In JSON, arrays [] only every have numeric keys, whereas objects {} have string properties. The inclusion of a array key in your second example forces the entire outer structure to be an object by necessity. The inner objects of both examples are made as objects because of the inclusion of string keys a,b,c,d.
If you were to use the JSON_FORCE_OBJECT option on the first example, you should get back a similar structure to the second, with the outer structure an object rather than an array. Without specifying that you want it as an object, the absence of string keys in the outer array causes PHP to assume it is to be encoded as the equivalent array structure in JSON.
$arrytest = array(array('a'=>1, 'b'=>2),array('c'=>3),array('d'=>4));
// Force the outer structure into an object rather than array
echo json_encode($arrytest , JSON_FORCE_OBJECT);
// {"0":{"a":1,"b":2},"1":{"c":3},"2":{"d":4}}
Arrays with continuous numerical keys are encoded as JSON arrays. That's just how it is. Why? Because it makes sense.
Since the keys can be expressed implicitly through the array encoding, there is no reason to explicitly encoded them as object keys.
See all the examples in the json_encode documentation.
At the first option you only have numeric indexes (0, 1 and 2). Although they are not explicitly declared, php automatically creates them.
At the second option, you declare one of the indexes as an string and this makes PHP internally transform all indexes to string.
When you json encode the first array, it's not necessary to show the integers in the generated json string because any decoder should be able to "guess" that they are 0, 1 and 2.
But in the second array, this is necessary, as the decoder must know the key value in your array.
It's pretty simple. No indexes declared in array? Them they are 0, 1, 2, 3 and so on.
output of this as in json form is year1{a,b},year2{c}, year3{d}
**a has value 1 ,b=2,c=3,d=4 stored in array of year1's a,b years2's c and years3's d respectivily
$array1 = array('a'=>1, 'b'=>2);
$array2 = array('c'=>3);
$array3 = array('d'=>4)
$form = array("year1" =>$array1,
"year2" =>$array2,
"year3" =>$array3,
);
$data = json_encode($form);

Problem with json_encode()

i have an simple array:
array
0 => string 'Kum' (length=3)
1 => string 'Kumpel' (length=6)
when I encode the array using json_encode(), i get following:
["Kum","Kumpel"]
My question is, what is the reason to get ["Kum","Kumpel"] instead of { "0" : "Kum", "1" : "Kumpel" }?
"{}" brackets specify an object and "[]" are used for arrays according to JSON specification. Arrays don't have enumeration, if you look at it from memory allocation perspective. It's just data followed by more data, objects from other hand have properties with names and the data is assigned to the properties, therefore to encode such object you must also pass the correct property names. But for array you don't need to specify the indexes, because they always will be 0..n, where n is the length of the array - 1, the only thing that matters is the order of data.
$array = array("a","b","c");
json_encode($array); // ["a","b","c"]
json_encode($array, JSON_FORCE_OBJECT); // {"0":"a", "1":"b","2":"c"}
The reason why JSON_FORCE_OBJECT foces it to use "0,1,2" is because to assign data to obeject you must assign it to a property, since no property names are given by developer (only the data) the encoder uses array indexes as property names, because those are the only names which would make sense.
Note: according to PHP manual the options parameters are only available from PHP 5.3.
For older PHP versions refer to chelmertz's answer for a way to make json_encode to use indexes.
As Gumbo said, on the JS-side it won't matter. To force PHP into it, try this:
$a = new stdClass();
$a->{0} = "Kum";
$a->{1} = "Kumpel";
echo json_encode($a);
Not that usable, I'd stick with the array notation.
Just cast as an object and it will work fine...the JSON_FORCE_OBJECT parameter does exactly the same thing.
json_encode((object)$array);
Don't forget to convert it back into a php array so you can access its values in php:
$array = (object)$array;
$array = (array)$array;
json_encode($array);
Since you’re having a PHP array with just numeric keys, there is no need to use a JavaScript object. But if you need one, try Maiku Mori’s suggestion.
I personally think this is a bug that needs to be fixed in PHP. JSON_FORCE_OBJECT is absolutely not an answer. If you try to do any sort of generic programming you get tripped up constantly. For example, the following is valid PHP:
array("0" => array(0,1,2,3), "1" => array(4,5,6,7));
And should be converted to
{"0": [0,1,2,3], "1": [4,5,6,7]}
Yet PHP expects me to either accept
[[0,1,2,3],[4,5,6,7]]
or
{"0":{"0":1,"1":1,"2":2,"3":3},"1":{"0":4,"1":5,"2":6,"3":7}}
Neither of which are right at all. How can I possibly decode an object like that? What possible reason is there to ever change something that is clearly using strings as indexes? It's like PHP was trying to be clever to help out idiotic people who can't differentiate strings from ints, but in the process messed up anyone legitimately using strings as indexes, regardless of what the value COULD be turned into.

Categories