array_merge before json encode in PHP - php

$myArray = array();
for($i=0;i<2;$i++){
..
.. //get the content logic here
assign it to array
$myArray["item"]["content"] = $item_content;
}
echo json_encode($myArray);
The above code produced this result:
Which has an error because I didn't merge them.
I tried to merge like this:
$finalJson = array_merge($finalJson, $myArray);
but the output of echo $finalJson is one object instead of 3.

Update:
Your real problem is down to your use of array_merge on an associative array. The behaviour of array_merge is to reassign duplicate keys if they are associative (cf the docs):
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.
And because $myArray is clearly using strings as keys, the values in $finalJson are being reassigned. What you need to do is either create unique keys on each iteration, or simply push the values of $myArray onto a numerically indexed $finalJson array (like I showed in my original answer below)
The problem is simply this:
$myArray["item"]["content"] = $item_content;
it's inside the loop, each time reassigning the value of $myArray["item"]["content"], and not adding it to the array. I suspect that what you wanted to do is add this at the bottom of your loop (for each new value of $myArray):
$finalJson[] = $myArray;
Then, on the next iteration, $myArray will be reassigned, and its new value will be appended to the $finalJson variable.

i have a tricky problem.
What i do.
I generate from the System Tables of Databases (DEV ,Test Prod setup) information for Tables, Vies trigger … with PHP and compare the results ti see teh differences with JavaScript.
Also I have a Documentation DB for additional business information which was installed only once on TEST DB.
Therfore I need to connect all four environments to get the data.
I use
if ($flag === 'i')
for information DB and
elseif ($flag === 's')
for system db‘s.
Result is $row_array and $info_array which must be combined and sendet back to Javascript.
$json_response = array_merge($rinfo, $rsql );
echo json_encode($json_response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);
I try this merge in a different positions in the program.
First time in
elseif ($flag === 'i') {
result json:
[
{
"0": "ACT",……….
} ][ ]
second time after } //ifelse return also 2 arrays
[{"0":"ACT","1":"Tabelle Akten","2":"hh","3":null,"4":null,"5":"UCC","6":"Y","7":"Reload Data in Test","8":"y","9":"delete all older tha","10":"n","11":" ","12":"y","13":" ","14":"o","15":"y","16":"o","17":"y","18":"y","19":"Diese tabelle speichert die Acten Verweise","20":"Gert Dorn","21":1570254359,"TDESCRIPTION":"n","TTYPE":" ","TREC_ESTIM":"y","TREC_GROWTH":" ","TDOMAIN":"o","TREL_TYPE":"y","TREL_RULES":"o","THOUSEKEEPING":"y","THOUSE_RULES":"y","TCID":"Diese tabelle speichert die Acten Verweise","TCID_RULES":"Gert Dorn","TUSE_UCC":1570254359,"TUSE_DWH":"","TUSE_ODS":"","TUSE_CWF":"","TUSE_IWF":"","TUSE_OWF":"","TUSE_DEP_MANAGER":"","TENTITY_DESCRIPTION":"","TOWNER":""
,"TTIMESTAMP":""**}][{**"0":"ACT","1":"DB2INST1"
,"2":"USERSPACE1","3":null,"4":"2018-11-21 16:43:20.066567","5":"2018-12-07 10:12:10.255759","6":null,"7":"2020-03-26","8":"2018-11-21 16:43:20.343258","9":3,"NAME":"ACT","CREATOR":"DB2INST1","TBSPACE":"USERSPACE1","REMARKS":"","CTIME":"2018-11-21 16:43:20.066567","STATS_TIME":"2018-12-07 10:12:10.255759","STATISTICS_PROFILE":"","LASTUSED":"2020-03-26","ALTER_TIME":"2018-11-21 16:43:20.343258","COLCOUNT":3}]
The program code and result you can download at
http://dmdg.io/dmdg.zip
Hope you can help Kind regards gert

Did you consider using array_push?
array_push is always preferred than myArray[] = $value

Related

Count the number of "columns" in an array (php)

I have the following JSON:
[
{
"0":"2019-08-31",
"1":"Bank Exp.",
"2":"AED",
"3":"30",
"4":"",
"5":"BANK FEE 10"
},
{
"0":"2019-08-31",
"1":"Inventory",
"2":"AED",
"3":"122",
"4":"",
"5":"DEPOSIT 10000"
},
{
"0":"2019-08-31",
"1":"Petty Cash",
"2":"AED",
"3":"4999",
"4":"",
"5":"DEPOSIT 10000"
}
]
I am trying to Count the number of elements or columns in the Json. The result should be 6.
I have tried with echo count($data_array); (or sizeof) result is 3 (number of rows). How can I count the "columns" in this Json, taking into account that I must set as number of column the Max number of column a specific row has?
Do I have to use a loop to count or can I do it with a single instruction?
Assuming that some var $json contains the JSON code you have above, you should be aware that the following code will result in an array of objects of type stdClass:
$data_array = json_decode($json);
So $data_array is in fact an array, but it contains objects. As you pointed out, this will return the number of rows in your JSON:
echo sizeof($data_array);
Clearly, the number of columns is not the number of rows. If you want to know the number of columns then you'll need to check one or more rows/objects/elements of your $data_array var. It's expedient to just look at the first element:
$col_count = sizeof($data_array[0]);
HOWEVER, this is going to cause an E_WARNING if $data_array's elements are objects of type stdClass:
PHP Warning: sizeof(): Parameter must be an array or an object that implements Countable in /tmp/foo.php on line 33
You could optionally use the second parameter of the json_decode function which will force PHP to decode every curly bracketed object in your JSON code as an associative array instead of stdClass objects:
$data_array = json_decode($json, TRUE);
$col_count = sizeof($data_array[0]);
This yields a $col_count value of6 which is the correct for the first object in your array. You should consider that later elements in $data_array may have either more or fewer columns, depending on the structure of your data. If you are sure that all elements will have the same number of columns, this is adequate, but if you have messy data, you may need to check every element of your data array to see what the true number of columns is:
$data_array = json_decode($json, TRUE);
$col_count = 0;
foreach($data_array as $row) {
$col_count = max($col_count, sizeof($row));
}
var_dump($col_count);
This will yield a $col_count value which reflects the maximum number of columns encountered in any element of your JSON. Clearly, there may be performance considerations if your JSON contains a large number of elements. It all depends on your JSON data and the nature of your application.
EDIT:
Instead of an explicit foreach loop, I think you can get away with this, but it will still require PHP to loop through your data structure. That said, it'll probably be faster:
$max_col_count = max(array_map("count", $data_array));
count($data_array) counts the number of elements in an array. In your case, is 3. But your array is multidimensional (matrix). So you need to count on some index to get the number of columns on that position:
<?php
echo count($data_array[0]);

PHP JSON Arrays within an Array

I have a script that loops through and retrieves some specified values and adds them to a php array. I then have it return the value to this script:
//Returns the php array to loop through
$test_list= $db->DatabaseRequest($testing);
//Loops through the $test_list array and retrieves a row for each value
foreach ($test_list as $id => $test) {
$getList = $db->getTest($test['id']);
$id_export[] = $getList ;
}
print(json_encode($id_export));
This returns a JSON value of:
[[{"id":1,"amount":2,"type":"0"}], [{"id":2,"amount":25,"type":"0"}]]
This is causing problems when I try to parse the data onto my android App. The result needs to be something like this:
[{"id":1,"amount":2,"type":"0"}, {"id":2,"amount":25,"type":"0"}]
I realize that the loop is adding the array into another array. My question is how can I loop through a php array and put or keep all of those values into an array and output them in the JSON format above?
of course I think $getList contains an array you database's columns,
use
$id_export[] = $getList[0]
Maybe can do some checks to verify if your $getList array is effectively 1 size
$db->getTest() seems to be returning an array of a single object, maybe more, which you are then adding to a new array. Try one of the following:
If there will only ever be one row, just get the 0 index (the simplest):
$id_export[] = $db->getTest($test['id'])[0];
Or get the current array item:
$getList = $db->getTest($test['id']);
$id_export[] = current($getList); //optionally reset()
If there may be more than one row, merge them (probably a better and safer idea regardless):
$getList = $db->getTest($test['id']);
$id_export = array_merge((array)$id_export, $getList);

json_encode changing array with one value to object

I"m creating a PHP script that handles JSON input (via a $_POST variable). It"s extracts data from the JSON and uploads it to an SQL database. I want the JSON in a particular format:
$object = json_decode('{
"key_a":[{"value_a":10,"value_b":7},{"value_a":10,"value_b":7},{"value_a":10,"value_b":7}],
"key_b":[{"value_a":10,"value_b":7}],
"key_c":[{"value_a":10,"value_b":7},{"value_a":10,"value_b":7}]
}',true);
Basically, an object with keys in, each of which should hold an array (no matter what size it is). I use json_decode(json,true) to convert it to an associative array (as opposed to object). I"ve had to add lots of checks in for each of the keys, checking if they"re objects or arrays (as the ASP.net page that the extract comes from converts arrays with single objects in, to objects - removing the array that holds them). The checks then convert them back to arrays, if there"s an object where I"d like an array holding an object:
if(is_object($object["key_b"]))
{
$a = array();
$a[] = $object["key"];
$object["key"] = $a;
}
I then iterate through the array, adding the values to rows in an SQL database. This all works fine, but when converting back to JSON with json_encode, any keys that hold arrays with only one object in, remove the array, and leave just the object under that key:
echo(json_encode($object));
// RETURNED JSON
'{
"key_a":[{"value_a":10,"value_b":7},{"value_a":10,"value_b":7},{"value_a":10,"value_b":7}],
"key_b":{"value_a":10,"value_b":7},
"key_c":[{"value_a":10,"value_b":7},{"value_a":10,"value_b":7}]
}'
You see, key_b no longer holds an array, but an object! This is really annoying, as I plan to create a JavaScript script that iterates through the arrays, adding one DOM element (div) for each of the objects.
Why does this happen? Is there any way to keep them as arrays, even if there"s only one object in the array?
I"ve tried:
if(is_object($object["key_b"]))
{
$a = array();
$a[] = array_values($object["key"]);
$object["key"] = $a;
}
and
if(is_object($object["key_b"]))
{
$a = array();
$a[0] = array_values($object["key"]);
$object["key"] = $a;
}
But it seems like nothing prevents json_encode from affecting the JSON in this way.
It"s not hard to get around this - but it means adding one check per key (checking whether it"s an array or value), which is particularly time consuming as the data extract that comes through is really big.
Any advice would be greatly appreciated.
EDIT: changed ' to " in JSON - though, this is only an example I just wrote to show the structure.
EDIT: I'm using references to cut my coding time down, if this changes anything?:
$t =& $object["key_b"];
if(is_object($t))
{
$a = array();
$a[] = $t;
$t = $a;
}
It appears using is_object() on a key of an associative array will not return true. I just knocked up this example, to prove this:
$json = json_decode('{"job_details":{"a":[{"x":5},{"y":23},{"z":18}],"b":{"x":19},"c":[{"x":64},{"y":132}]}}',true);
echo(json_encode($json)."<br><br>");
$t =& $json["job_details"]["b"];
if(is_object($t))
{
$a = array();
$a[] = $t;
$t = $a;
echo("IS OBJECT<br><br>");
}
echo(json_encode($json));
I will find another means of checking what value is held within an associative arrays key.
I was actually trying to find whether the value in the key is an associative array or not (not an object) - I just didn't realise they were different in PHP.
I must just use this custom function:
function is_assoc($array)
{
return (bool)count(array_filter(array_keys($array), 'is_string'));
}
From: How to check if PHP array is associative or sequential?
Which returns true if the value is an associative array.

Access JSON values in PHP

{"coord":{"lon":73.69,"lat":17.8},"sys":{"message":0.109,"country":"IN","sunrise":1393032482,"sunset":1393074559},"weather":[{"id":800,"main":"Clear","description":"Sky is Clear","icon":"01n"}],"base":"cmc stations","main":{"temp":293.999,"temp_min":293.999,"temp_max":293.999,"pressure":962.38,"sea_level":1025.86,"grnd_level":962.38,"humidity":78},"wind":{"speed":1.15,"deg":275.503},"clouds":{"all":0},"dt":1393077388,"id":1264491,"name":"Mahabaleshwar","cod":200}
I am trying to fetch description from the weather from the json above but getting errors in php. I have tried the below php code:
$jsonDecode = json_decode($contents, true);
$result=array();
foreach($jsonDecode as $data)
{
foreach($data{'weather'} as $data2)
{
echo $data2{'description'};
}
}
Any help is appreciated. I am new in using json.
You have to use square brackets ([]) for accessing array elements, not curly ones ({}).
Thus, your code should be changed to reflect these changes:
foreach($data['weather'] as $data2)
{
echo $data2['description'];
}
Also, your outer foreach loop will cause your code to do something completely different than you intend, you should just do this:
foreach($jsonDecode['weather'] as $data2)
{
echo $data2['description'];
}
Your $jsonDecode seems to be an array, so this should work-
foreach($jsonDecode['weather'] as $data)
{
echo $data['description'];
}
You can access data directly with scopes
$json = '{"coord":{"lon":73.69,"lat":17.8},"sys":{"message":0.109,"country":"IN","sunrise":1393032482,"sunset":1393074559},"weather":[{"id":800,"main":"Clear","description":"Sky is Clear","icon":"01n"}],"base":"cmc stations","main":{"temp":293.999,"temp_min":293.999,"temp_max":293.999,"pressure":962.38,"sea_level":1025.86,"grnd_level":962.38,"humidity":78},"wind":{"speed":1.15,"deg":275.503},"clouds":{"all":0},"dt":1393077388,"id":1264491,"name":"Mahabaleshwar","cod":200}';
$jsonDecode = json_decode($json, true);
echo $jsonDecode['weather'][0]['description'];
//output Sky is Clear
As you can see wheater` is surrounded with scopes so that means it is another array. You can loop throw that array if you have more than one result
foreach($jsonDecode['weather'] as $weather)
{
echo $weather['description'];
}
Live demo
If the result of decode is an array, use:
$data['weather']
If the result is an object, use:
$data->weather
you have to access "weather" with "[]" operator
like this,
$data["weather"]
There is several things worth answering in your question:
Q: What's the difference between json_decode($data) and json_decode($data, true)?
A: The former converts JSON object to a PHP object, the latter creates an associative array: http://uk1.php.net/json_decode
In either case, there is no point on iterating over the result. You probably want to access just the 'weather' field:
$o = json_decode($data) => use $weather = $o->weather
$a = json_decode($data, true) => use $weather = $a['weather']
Once you have the 'weather' field, look carefully what it is:
"weather":[{"id":800,"main":"Clear","description":"Sky is Clear","icon":"01n"}]
It's an array, containing a single object. That means you will either need to iterate over it, or use $clearSky = $weather[0]. In this case, it does not matter which approach of json_decode did you choose => JSON array is always decoded to a PHP (numeric indexed) array.
But, once you get $clearSky, you are accessing the object and it again matters, which approach you chose - use arrow or brackets, similarly to the first step.
So, the correct way to get for exaple the weather description would be either of these:
json_decode($data)->weather[0]->description
json_decode($data, true)['weather'][0]['description']
Note: In the latter case, dereferencing result of the function call is supported only in PHP 5.4 or newer. In PHP 5.3 or older, you have to create a variable.
Note: I also encourage you to always check if the expected fields are actually set in the result, using isset. Otherwise you will try to access undefined field, which raises an error.

In PHP, filter an Array of Associative Arrays

In PHP, are there any inbuilt functions to turn
[{"id":1, "name":"John"}, {"id":2, "name":"Tim"}]
into
[{"id":1}, {"id":2}]
?
I've used JSON to describe the objects above, but that's just a conceptual representation of my array of associative arrays. I don't want to have to loop manually - something short and elegant I can fit on one line would be nice.
One line, using array_map:
$arr = json_decode('[{"id":1, "name":"John"}, {"id":2, "name":"Tim"}]');
$new_arr = array_map(function($el){$ret=array("id"=>$el->id);return $ret;},$arr);
var_dump(json_encode($new_arr));
array_map(function($arr){return $arr[0];}, $array);
This should do it.
Edit As noted by Jonathon Hibbard, you could pass array element by reference, this way you do not to assign result of the function and just use changed old array. The code should then be modified appropriately.
First decode json by json_decode. You will get an array. Then follow this link to remove an index from an associative array. Then again decode it. It should work.
do something like:
$array = json_decode($some_json_string, true);
array_walk($array, function($value, $key) use(&$array) {
if($key == "name") {
unset($array[$key]);
}
});
Edit:
Cthulhu's answer won't get ya there without re-assigning it. Could use it as a reference though (equal to the walk. though if you want to use the map, its a bit better not to reallocate with a brand new array copy and just pass it by reference, then remove the key with an unset within it and move on.)
array_map(function(&$array) { unset($array['name']; }, $array);

Categories