Confusion with JSON_DECODE second param - php

I just created a small program to check JSON and JSON_FORCE_OBJECT
$tree = [
0 => array
(
'id' => 1,
'parent' => '0',
'name' => 'b',
'surname' => 'myfolder/b'
),
1 => array
(
'id' => 2,
'parent' => 1,
'name' => 'ignore',
'surname' => 'myfolder/ignore2'
),
2 => array
(
'id' => 3,
'parent' => 1,
'name' => 'ignore2',
'surname' => 'myfolder/ignore4'
)
];
var_dump($tree);
$try = json_encode($tree);//To print with key. Also if we decode we get result as object
//echo $try;
echo '<br />';
$try2 = json_decode($try,JSON_FORCE_OBJECT);
var_dump($try2);
$try2 is exactly equal to $tree an associative array.
Whereas if I remove JSON_FORCE_OBJECT from this line
$try2 = json_decode($try,JSON_FORCE_OBJECT);
I get an array with child object. Though JSON_FORCE_OBJECT is supposed to be used with json_encode but using it with json_decode, I get a surprising result. I am unable to understand whats going on inside?? I thought when I encode it and decode it I should get same result. But I got the same result only when I used JSON_FORCE_OBJECT. Can anyone please help why this happens?

According to the manual: http://php.net/manual/en/function.json-decode.php
json_decode returns an array of objects if you want to convert them in assoc array you should specify the second param which is a boolean
JSON_FORCE_OBJECT is an int with value 16...
when this is passed as second param php cast/converts it to its bool equivalent which true.
To test the above stated behavior try:
var_dump((bool)1; (bool)2, (bool)16)
//output bool(true) bool(true) bool(true) .
var_dump((bool)0)
//outputs bool(false)
So it's nothing to do with JSON_FORCE_OBJECT...even
json_decode($try,true);
json_decode($try,2);
json_decode($try,3);
json_decode($try,4);
json_decode($try,'someVar');
....
//should return your expected result (assoc array)
Similarly if you pass 0 as second param PHP will cast it into bool (which is false) and returns you an object
json_decode($try,0);
json_decode($try,false);
json_decode($try,null)
json_decode($try)
...
//will return objects

The second parameter to json_decode is a boolean. It accepts true or false. It does not accept JSON_FORCE_OBJECT. You're trying to use the wrong constant for the wrong function.
json_decode's 4th parameter accepts a bitmask of constants, but currently it only supports JSON_BIGINT_AS_STRING.
If you want to return stdClass instances for JSON objects from json_decode, set its second parameter to false (the default). Setting it to any non-falsey value makes it return associative arrays instead of objects. Setting it to JSON_FORCE_OBJECT counts as "not-falsey".
It's all described in the manual: http://php.net/json_decode

Related

PHP - Convert foreach to arrays

Anyone can help me
I have a little problem with the following code
foreach ($products as $product) {
$product->name;
$product->code;
...
}
My output code with var_dump($products)
array
0 =>
object(stdClass)
...
...
...
1 =>
object(stdClass)
...
...
...
And I need output something like this
$output = array(
array('name' => 'item1', 'code' => 'code1', 'price' => '10.00'),
array('name' => 'item2', 'code' => 'code2', 'price' => '20.00')
);
For this purpose, there is a function is php json_decode()
mixed json_decode ( string $json [, bool $assoc = false [, int $depth
= 512 [, int $options = 0 ]]] )
Need to use this function sensibly.
As you see in the function description,
The function's three parameters:
1) Variable to be converted.
2) Return as associative array.
3) Depth: default => 512. Means upto depth of 512 levels (in case of multi-dimensional array or complex object), the child elements will be converted into arrays if second parameter is set to true.
First encode your variable by json_encode() and the decode it with using
json_decode().
json_decode() 's second parameter should be set to true.
This true means return associative array instead of original type.
Pseudo code:
$output = json_decode(json_encode($yourVar), TRUE);

Encode associative array as valid php

Is there a way to encode variables as strings that can be evaluated as php code? In particular, I'm interested in associative arrays. (Scalar values and indexed arrays are encoded as valid php code by json_encode. I don't need to encode objects and resources).
$Array = ['1', 2, 'key' => 'value'];
php_encode($Array); // => "[0 => '1', 1 => 2, 'key' => 'value']" or similar
You can use var_export with the second parameter set to true:
function php_encode($val)
{
return var_export($val, true);
}
http://php.net/manual/en/function.var-export.php

How can I force PHP's json_encode integer values to be encoded as String?

I'm using PHP v5.6.
As i read that php json_encode function is automatically converting int to string. But not in my case. Json_encode is still return it to int not string.
Like example:
json_encode(['code' => 200, 'results' => [id=> 1]]);
my expected results is all become a string. but what i get is
{"code":200,"results":{"id": 1}}
Expected output:
{"code":"200","results":{"id": "1"}}
How can i change all the result become string without using "" for every value?.
NB: results array is based on query.
In the link posted by Thomas in comments, one user suggests that you do this:
$data = json_encode(array_map('strval', $data));
This might not be the most efficient in terms of performace though, since every entry on the array will pass through the strval function.
json_encode(['code' => 200, 'results' => [id=> strval(1)]]);
With strval() php will return
The string value of var.
To ensure that all numeric "leaf nodes" of a potentially multi-dimensional array are cast as strings, call array_walk_recursive() and make conditional changes to each value type. By checking if the value "is numeric", you prevent values like null and booleans from being cast as strings.
Code: (Demo)
$array = [
'code' => 200,
'results' => [
'id' => 1
],
'a' => [
[
'b' => [
4,
null,
false
]
]
]
];
array_walk_recursive(
$array,
function(&$v) {
if (is_numeric($v)) {
$v = strval($v);
}
}
);
echo json_encode($array);
Output:
{"code":"200","results":{"id":"1"},"a":[{"b":["4",null,false]}]}

PHP isset returns true but should be false

My project is in cakePHP but I think this is an aspect of native PHP that I am misunderstanding..
I have an afterFind($results, $primary = false) callback method in my AppModel. On one particular find if I debug($results); I get an array like this
array(
'id' => '2',
'price' => '79.00',
'setup_time' => '5',
'cleanup_time' => '10',
'duration' => '60',
'capacity' => '1',
'discontinued' => false,
'service_category_id' => '11'
)
In my afterFind I have some code like this:
foreach($results as &$model) {
// if multiple models
if(isset($model[$this->name][0])) {
....
The results of the find are from my Service model so inserting that for $this->name and checking if(isset($model['Service'][0])) should return false but it returns true? if(isset($model['Service'])) returns false as expected.
I am getting the following PHP warning:
Illegal string offset 'Service'
so what's going on here? why does if(isset($model['Service'][0])) return true if if(isset($model['Service'])) returns false?
UPDATE:
I still don't know the answer to my original question but I got around it by first checking if $results is a multidimensional array with
if(count($results) != count($results, COUNT_RECURSIVE))
Use array_key_exists() or empty() instead of isset(). PHP caches old array values strangely. They have to be manually unset using unset()
isset() does not return TRUE for array keys that correspond to a NULL value, while array_key_exists() does.
String offsets provide a mechanism to use strings as if they were an array of characters:
$string = 'abcde';
echo $string[2]; // c
$model is indeed a string for all keys except discontinued.
As for the isset($model['Service'][0]) return value, I'm a bit surprised. This is a simplified test case:
$model = '2';
var_dump(isset($model['Service'])); // bool(false)
var_dump(isset($model['Service'][0])); // bool(true)
There must be a reason somewhere. Will have a dig..

How can I fix this error about stdClass in PHP

This is my code:
$array = array(
"Birds" =>
array(
'group' => 1,
"Bird" => array(
array('id' => 1, 'img' => "img1.png", 'title' => "kate"),
array('id' => 2, 'img2' => "img2.png", 'title' => "mary")
)) );
$json = json_encode($array);
echo json_decode($json);
OUTPUT IS:
//JSON OUTPUT {"Birds":{"group":1,"Bird":[{"id":1,"img":"img1.png","title":"cardinal"},{"id":2,"img2":"img2.png","title":"bluejay"}]}}
Object of class stdClass could not be converted to string
try
var_dump($json);
This allows you to print out the details of objects and other non-primative types.
Echoing is used for strings - Your json decoded string will be an object of type stdClass
See var_dump http://php.net/manual/en/function.var-dump.php
See echo http://php.net/manual/en/function.echo.php
You have to pass the second parameter of json_decode as true, more info about these parameters at: http://php.net/manual/en/function.json-decode.php
so your echo json_decode($json); should be changed to this:
print_r(json_decode($json, true));
echo is changed to print_r since the output is an array not a string ...
Use var_dump to view variables echo converts your variable to string, while it's object. Also you can add second param to json_decode($data, true) to get array instead object, as i assume that's what you want, because input is array.
About object convertion to string you can read __toString

Categories