PHP json_decode() depth meaning - php

I'm saving some JSON and I don't know if this might later nib me in the butt if the JSON gets too big(The size depends on user input), though from my reading the max depth of 512 seems to be quite a high number and not really practical, but it triggered something in my mind and I've only now realized that I don't quite understand the meaning of "depth" of an array or how to count it (visually)...
I checked out this question while trying to get a clear understanding of depth: What is the purpose of using depth in JSON encode?
And the example given was:
array(
'foo',
'bar',
'baz'
)
// Has depth of 1
array(
array(
'foo'
),
array(
'bar'
),
array(
'baz'
)
)
// Has depth 2
But what about...
array(
array(
'foo'
),
array(
'bar'
),
array(
array(
'baz' => 'caz'
)
)
Or
array(
array(
'foo'
),
array(
'bar'
),
array(
array(
'baz' => 'caz'
),
array(
'tree' => array(
'tree-a' => array(
'car-a' => 'car-b'
)
)
)
)
I know this might be obvious to some but it's just one of those things I never thought much about. I did check out the documentation for json_decode() and it's depth parameter but still couldn't wrap my head around it. Maybe there's some rule of thumb i can use?
I'm trying to understand this in the context of when using json_decode();

Related

Simpliest way to build a multi-dimensional array with SQL result?

I am currently building a web planning and I want to show some data in the period display.
I have a PHP file where I create my SQL request over ~13 tables and fetch all results (I use PDO::FETCH_ASSOC), then I have to loop over my result to build the array I want.
The problem is I need to build a complicated array with lot of data. Here is the kind of result I want to achieve :
$result = array(
$place_1 => array(
'data_place' => array(
'id' => ...,
'name' => ...,
// etc.
),
'data_target' => array(
$target_type_1 => array(
$name_1 => ...,
$name_2 => ...,
// etc.
),
$target_type_2 => array ( ... ),
// etc.
),
'data_isOpen' => array(
$day_1 => array(
$hour_begin => ...,
$hour_end => ...
),
$day_2 => array ( ... ),
// etc.
),
'data_box' => array(
// same kind of stuff with more dimension
)
),
...
$place_n = array(
// same
)
);
When I execute my request, I get something like 3000 array with all the data I need, but I only have 29 places in database so there is a lot of repetition...
$result = array(
0 => array(
"id" => ...,
"name" => ...,
// the list of all fields I need in my big array
),
...
n => array(
// same
)
);
I almost manage to achieve the result I want with some "foreach" and headaches but here is my question :
Is it possible to build a SQL request and fetch the result as I want? I mean, can I group all the result by "id_place" for example but wihtout lost information? And if it's possible, can we do it multiple time?
The idea is to get a result with one array for every place (so 29 and not 3000), then for every "place array", group for example the "hour_begin" and "hour_end" by "opening_day", etc...
Sorry if it's a duplicate, I didn't saw any positive anwser to my question so I try again !

What is the purpose of using depth in JSON encode?

I have this example code:
$array = array(
'GiamPy' => array(
'Age' => '18',
'Password' => array(
'password' => '1234',
'salt' => 'abcd',
'hash' => 'whirlpool'
),
'Something' => 'Else'
)
);
echo json_encode($array, JSON_PRETTY_PRINT);
I have seen in the PHP documentation that, since PHP 5.5.0 (thus recently), json_encode allows a new parameter which is the depth.
What is its purpose?
Why would I ever need it?
Why has it been added in PHP 5.5.0?
The option limits the depth that will be processed (d'uh). The depth of an array is measured by how deep it is nested. This is an array of depth 1:
array(
'foo',
'bar',
'baz'
)
This is an array of depth 2:
array(
array(
'foo'
),
array(
'bar'
),
array(
'baz'
)
)
// ------ depth ------>
If the input surpasses the maximum depth (by default 512), json_encode will simply return false.
Why you may use this is debatable, you may want to protect yourself from inadvertent infinite recursion or too much resource use. An array which is deeper than 512 levels probably has infinitely recursive references and cannot be serialised. But if you are sure your array is not infinitely recursive yet is deeper than 512, you may want to increase this limit explicitly. You may also want to lower the limit as a simple error catcher; say you expect the result to have a maximum depth but your input data may be somewhat unpredictable.

Odd array_merge_recursive behavior with string keys

I'm trying to use array_merge_recursive to merge two data structures.
<?php
$testSite = array(
'name' => 'test site',
'modules' => array(
'foo' => 'true',
'bar' => 'true'
)
);
$testData = array(
'modules' => array(
'bar' => 'false'
)
);
$testSite = array_merge_recursive($testSite, $testData);
Note that I'm using strings instead of booleans for debug printing purposes
I would expect $testSite to be the exact same after this code has ran, except for the modules.bar property, which I'd expect to see being changed to false. What happens instead, as seen in this live example, is that bar is turned into an array containing it's old value and the value false is appended to that.
The documentation page reads that this is what will happen for numeric keys, but these are all strings keys. Can anyone shed some light on this?
I think you want array_replace_recursive.
array_merge_recursive() vs. array_replace_recursive()

PHP Lithium: Filtering an existent DocumentSet and get first Match

I am retrieving a DocumentSet in Lithium from MongoDB, but I don't want to process the documents all at once. Instead I would like to have a filter, which I just could tell something like this:
$manyDocuments->giveMeTheOneWhere(array('foo' => 'bar'));
I already tried to do it this way, but it didn't work:
$manyDocuments->find(function($singleDocument){
return ($singleDocument->foo == 'bar');
});
Even if I manually return true inside the closure, it always returns an empty DocumentSet.
Just to add clarity: I am not looking for a database-operation, instead I want to get one out of an already existent DocumentSet. Is there a fancy way to achieve this or do I need to iterate through the set using a custom function?
That looks right to me. Is that the exact code you are using?
For example, is the 'bar' value you are using something you are passing in?
I'm on the latest of the master branch of Lithium and wrote this unit test which works for me. I'm not really sure why you're getting an empty DocumentSet.
$docs = new DocumentSet(array('data' => array(
new Document(array('data' => array(
'id' => 1,
'foo' => 'bar'
))),
new Document(array('data' => array(
'id' => 2,
'foo' => 'baz'
))),
new Document(array('data' => array(
'id' => 3,
'foo' => 'bar'
))),
new Document(array('data' => array(
'id' => 4,
'blah' => 'ack'
)))
)));
$filtered = $docs->find(function($doc) {
return $doc->foo === 'bar';
});
$expected = array(
'0' => array('id' => 1, 'foo' => 'bar'),
'2' => array('id' => 3, 'foo' => 'bar')
);
$this->assertIdentical($expected, $filtered->data());
Instead of using find() I just used first() with a closure. This works as expected. Sadly that was the only thing I didn't try before. Excuse me for answering my own question.
Anyway I'd still be interested in a way to get another Document Set.

Insert new values in Sub-Arrays in PHP

I have array like this:
array(
'person0' => array( 'name'=>'name0','address'=>'address0' ),
'person1' => array( 'name'=>'name1','address'=>'address1' ),
'person2' => array( 'name'=>'name2','address'=>'address2' )
);
I want to change it like this. (just append a new value in each sub-array)
array(
'person0' => array( 'name'=>'name0','address'=>'address0','type'=>'type0' ),
'person1' => array( 'name'=>'name1','address'=>'address1','type'=>'type1' ),
'person2' => array( 'name'=>'name2','address'=>'address2','type'=>'type2' )
);
Is there any related function in php to perform this action? What is the shortest way to do this. Is it possible without loop?
Thanks
Browse the PHP manual when you wonder if a function exists to do something... it probably does.
http://www.php.net/manual/en/function.array-walk.php
http://php.net/manual/en/function.array-map.php
I'd just write the loop, but you can use those functions if you don't want to.

Categories