PHP - Parse Nested JSON Array via Loop - php

I'm working with some JSON data like this:
{
"attachments": [
{
"content": "<base 64 encoded attachment>",
"content_type": "image/jpeg",
"original_name": "image000000.jpg"
},
{
"content": "<base 64 encoded attachment>",
"content_type": "image/gif",
"original_name": "gif0001.jpg"
}
],
"source_number": "++614567890"
}
I need to loop through all the attachments array. I can get individual elements like this:
$arr = json_decode($jsonobj, true);
echo $arr[attachments][0]["content_type"]; // returns image/jpeg
but I can't work out the syntax to loop through all of the attachments array and retrieve the values for each of these, something like this pseudo code:
foreach($arr[attachments] as $key => $value) {
$contentType = $arr[attachments][0]["content_type" ;
$content = $arr[attachments][0]["content" ;
$originalName = $arr[attachments][0]["original_name" ;
}
that will generate a variable in the loop for each item in the attachments array.

You don't need the $key, you just need the $value. In the loop, $value is associative array that has the keys content, content_type and original_name:
foreach($arr["attachments"] as $value) {
$contentType = $value["content_type"];
$content = $value["content"];
$originalName = $value["original_name"];
}

You are almost there: $value['content_type'] (and so on) inside your loop will do the trick. (The $key is superfluous.)
Oh and you should use $arr['attachments'] instead of $arr[attachments] probably.

Related

PHP - Help Needed Creating Array in a Loop

I'm processed some JSON data that is sent via HTTP POST to my PHP file. I then need to extract some elements and create a PHP array containing these, so I can then loop through this array and perform some actions.
Here's a sample of how the JSON data that is sent looks:
[
{
"fileName": "Invoices",
"event": "processed",
"serverName": "server1.acme.com",
"timestamp": 1574229999
},
{
"fileName": "Invoices",
"event": "processed",
"serverName": "server2.acme.com",
"timestamp": 1574228341
},
{
"fileName": "Payments",
"event": "processed",
"hostname": "server3.acme.com",
"timestamp": 1574766997
}
]
I'm then decoding this to parse out just the elements I need:
$payload = #file_get_contents('php://input');
$records= json_decode( $payload, FALSE );
$sessionsArray = array();
foreach($records as $record){
$hostname = $record->hostname;
$fileName = $record->fileName;
// need to add these to the $sessionsArray for each iteration of the loop
}
I would like to create a new array $sessionsArray and add the $hostname and $fileName variables to this for each iteration in the foreach loop. I then intend to do another foreach on the $sessionsArray and perform some actions using the $hostname and $fileName for each element of the array.
I'm stuck on how to add the variables within the first foreach loop to the $sessionsArray array so I can then subsequently loop through that array.
foreach($records as $record){
$sessionsArray[] = [
'hostname' => $record->hostname,
'fileName' => $record->fileName,
];
}
And then you can do:
foreach($sessionsArray as $entry){
$hostname = $entry['hostname'];
$fileName = $entry['fileName'];
}
=== OR ===
foreach($records as $record){
$sessionsArray[$record->hostname] = $record->fileName;
}
and then you can do:
foreach($sessionsArray as $hostname => $fileName){
// $hostname contains the hostname
// $filename contains filename
}
Just FYI, based on the JSON object you provided your code SHOULD be:
$hostname = $record->serverName;
$fileName = $record->fileName;
$sessionsArray = array();
foreach($records as $key => $record){
$sessionsArray[$key]['hostname'] = $record->hostname;
$sessionsArray[$key]['fileName'] = $record->fileName;
}
You need to get the last key of sessionsArray before every loop and pass that last key while adding to variable.
Here is example:
$sessionsArray = !empty($sessionsArray)?$sessionsArray:[];
$continueKey = (#array_pop(array_keys($sessionsArray)))?#array_pop(array_keys($sessionsArray))+1:0;
foreach($records as $record){
$sessionsArray[$continueKey]['hostname'] = $record->hostname;
$sessionsArray[$continueKey]['fileName'] = $record->fileName;
}

Failed to modify JSON file in PHP

This is my json.json file content
{
"Title": "Hello World",
"Inputs": [
{
"Id": "1",
"Title": "One"
},
{
"Id": "15",
"Title": "Fifteen"
}
]
}
I am trying to modify it as the follows -
$text = file_get_contents("json.json");
$json = json_decode($text,true);
foreach($json["Inputs"] as $input){
if($input["Id"]== "15"){
$input["Title"] = "This is from me.";
}
}
$new = json_encode($json);
file_put_contents('json.json', $new);
But the file is not being updated.
Any idea?
Your JSON in the example is improperly formatted, but the issue you are having is that you do not set the title in the original array. You change the copy that is passed to the foreach loop.
Change your foreach loop to this and your changes should be shown:
foreach($json["Inputs"] as $key => $input){
if($input["Id"]== "15"){
$json["Inputs"][$key]["Title"] = "This is from me.";
}
}
The foreach loop takes the value by reference, so changing the $json['Inputs'] will change the original value, whereas changing $input modifies the copy that is passed to the loop, and does not change the original json data. There are ways to pass by reference to the foreach loop, but this seems like a simpler solution.

JSON Get the name of dynamically changing key with PHP

I am having trouble getting the name of a dynamic key from a JSON string.
I am using PHP
This is a sample of the JSON
{
"_text": "this is a test",
"entities": {
"dynamic_key": [
{
"confidence": 0.99,
"value": "thi is the answer"
}
]
},
"msg_id": "1234532123"
}
I am using foreach to go trough the json key and get the values
foreach ($json as $obj) {
$search_term = $obj->_text;
$msg_id = $obj->msg_id;
}
But I am not sure how to get the value of the "dynamic_key" which changes every time, and because of that I also cannot get the values of "confidence and value" keys.
Any ideas on how to approach this?
Followed #Dimi, solution. This is what I ended up with
$data=json_decode($json,true);
foreach ($data['entities'] as $key=>$val)
{
echo "Entity: $key";
foreach ($data['entities'] as $keys){
$conf = $keys[0]['confidence'];
$answer = $keys[0]['value'];
echo "conf: $conf, answ: $answer";
}
}
Can you provide a couple more examples?
Or try this code and let us know if it breaks
<?php
$json='{
"_text": "this is a test",
"entities": {
"dynamic_key": [
{
"confidence": 0.99,
"value": "thi is the answer"
}
]
},
"msg_id": "1234532123"
}';
$data=json_decode($json,true);
foreach ($data['entities'] as $key=>$val)
{
echo "VALUE IS $key\n values are ";
var_dump($val);
}
Using the data you've shown, there doesn't seem to be an array for the starting JSON.
But with that data the following will use foreach to both fetch the key and the data and then another sub-loop to fetch the confidencevalue...
$search_term = $json->_text;
$msg_id = $json->msg_id;
foreach ( $json->entities as $key => $entities ) {
echo $key.PHP_EOL;
foreach ( $entities as $entity) {
echo $entity->confidence.PHP_EOL;
}
}
If you decode the JSON as an array and if the dynamic key is the only key under entities, then:
$array = json_decode($json, true);
$dynamic = current($array['entities']);
$confidence = $dynamic['confidence'];
$value = $dynamic['value'];
Or shorter:
$confidence = current($array['entities'])['confidence'];
You can probably use reset, current and maybe array_pop etc.

Create JSON response from Parsed XML PHP

I am parsing thorugh a eBay API response. I want to deliver this back to a website cleaner and easier to parse with JavaScript. I successfuly Parsed through the XML... but now turning that into JSON to resend back to the client is giving me some headaches.
NOTE: $resp is the response from eBay. It's their full length XML that is successfully parsed with the code below.
For example... $valueName could be Grade. And then I go into the next foreach loop and get the values for this. These values may be 10, 9.5, 9 etc.
Here is my PHP code.
$arrayName = array();
$arrayValue = array();
foreach($resp->aspectHistogramContainer->aspect as $name) {
$nameAspect = $name['name'];
//$arrayName["aspectName"] = $nameAspect;
foreach($name->valueHistogram as $value) {
$valueAspect = $value['valueName'];
//$arrayValue["aspectValue"] = $valueAspect;
}
//array_push($arrayName, $arrayValue);
}
echo json_encode($arrayName);
So, without me trying to create my own JSON, I am getting that I need. I echos results and it was similar to this...
NAME
----- Value
----- Value
----- Value
NAME
----- Value
NAME
etc etc
For a JSON response... Im looking for something like...
[
{
"name": "NAME",
"value": ["value", "value"]
}, {
"name": "name",
"value": ["value", "value"]
}
]
Any help and guidance would be greatly appreciated.
eBay's response is like this (there are A LOT more <aspect> and <valueHistogram>)
<getHistogramsResponse xmlns="http://www.ebay.com/marketplace/search/v1/services">
<ack>Success</ack>
<version>1.13.0</version>
<timestamp>2018-11-07T15:32:20.380Z</timestamp>
<aspectHistogramContainer>
<domainDisplayName>Baseball Cards</domainDisplayName>
<aspect name="Card Manufacturer">
<valueHistogram valueName="Ace Authentic">
<count>19</count>
</valueHistogram>
<valueHistogram valueName="American Caramel">
<count>2024</count>
</valueHistogram>
<valueHistogram valueName="APBA">
<count>10554</count>
</valueHistogram>
<valueHistogram valueName="Bazooka">
<count>8826</count>
</valueHistogram>
<valueHistogram valueName="Be A Player">
<count>17</count>
</valueHistogram>
<valueHistogram valueName="Bell Brand Dodgers">
<count>334</count>
To encode it (and assuming SimpleXML), then it's just a case of building each internal $aspect data array and then adding the values to it. I use (string) to ensure the data is not stored as a SimpleXMLElement, which can cause side effects...
$arrayName = array();
foreach($resp->aspectHistogramContainer->aspect as $name) {
$aspect = [ "name" => (string)$name['name']];
foreach($name->valueHistogram as $value) {
$aspect["value"][] = (string)$value['valueName'];
}
$arrayName[] = $aspect;
}
echo json_encode($arrayName);
with the sample XML, this gives...
[{"name":"Card Manufacturer","value":["Ace Authentic","American Caramel","APBA","Bazooka","Be A Player","Bell Brand Dodgers"]}]
Create one single array $resultArray and store values in it. By maintaining your current code structure with minimal changes, here is the updated code snippet,
$resultArray = array();
$i = 0; // Maintain Array Index value
foreach($resp->aspectHistogramContainer->aspect as $name) {
$resultArray[$i]["aspectName"] = (string)$name['name'];;
foreach($name->valueHistogram as $value) {
$resultArray[$i]["aspectValue"][] = (string)$value['valueName'];
}
$i++; // Increment array index to store next value
}
echo json_encode($resultArray);
$results = array();
// Parse the XML into a keyed array
foreach($resp->aspectHistogramContainer->aspect as $name) {
$nameAspect = (string) $name['name'];
$values = array();
foreach($name->valueHistogram as $value) {
$values[] = (string) $value['valueName'];
}
$results[$nameAspect] = $values;
}
// This keeps things simple - rewrite to the required JSON format
$outputForJSON = array();
foreach ($results as $name => $values) {
$outputForJSON[] = array(
"name" => $name,
"values" => $values
);
}
echo json_encode($outputForJSON);

How to add data in JSON using PHP

I have a json file with the following syntax:
[
{
"fields": {
"service_number": "service_number",
"physical_address": "physical_address",
"account_id": "account_id",
"contact_id": "contact_id"
},
"someId": "asd23f",
"status": "Active",
"perCode": "1",
"idCode": "0987",
"nextCode": "09"
},
{
"fields": {
"service_number": "service_number",
"physical_address": "physical_address",
"account_id": "account_id",
"contact_id": "contact_id"
},
"someId": "789096",
"status": "Active",
"perCode": "1",
"idCode": "076543",
"nextCode": "09"
}
]
I would like to use a for loop in order to add something like a userID before or after the nextCode. Is there any solution to this?
So far, I tried this:
$data = json_decode($file, true);
foreach ($data as $key => $val)
{
foreach ($val as $key=>$c)
{
if (is_array($c))
continue;
$data .= $data . "user_id:$userId";
}
}
Of course it does not make the trick, any ideas please?
There are a few problems.
First, the foreach loop works with a copy of the array it's iterating, so modifying one of the items there won't change the original array.
Then, your inner foreach loop is overwriting the $key from the outer loop. That would cause problems, but it's okay, because you don't actually need the inner loop.
Finally, after you've decoded the JSON string, $data will be an array, so appending to it with .= won't work, and even if it did, you'd just be sticking something on the end of it rather than at the specific point where your loop is.
Just refer to the specific key you need and set the value there.
$data = json_decode($file, true);
foreach ($data as $key => $val)
{
$data[$key]['user_id'] = $userId;
}
$data = json_encode($data);
Another way which is slightly shorter is pass the value by reference &:
$data = json_decode($file, true);
foreach ($data as &$val) {
$val['user_id'] = $userId;
}
https://3v4l.org/ZF4Ve
This is how you can add an element to a parsed JSON and recostruct it back into a JSON:
// parse the JSON into an array
$data = json_decode($file, true);
foreach ($data as $key => $val)
{
// add the userID to each element of the main array
// it will be inserted after the last element (after nextCode)
$data[$key]['userID'] = 'some-id';
}
// if needed, parse the array back to JSON
$data = json_encode($data);
I explain to you
The following expression converts the information from string to array
$data = json_decode ($file, true);
So in your foreach you only have to add the key
$data = json_decode($file, true);
foreach ($data as $key => $val)
{
foreach ($val as $k=>$c)
{
if (is_array($c))
continue;
$data[$k]['user_id'] = $userId;
}
}
I see everybody answered for array options. I don't see why not using object, though.
I would do it like this:
$data = json_decode($file);
foreach ($data as &$field)
{
$field->userID = $userId;
}
$data = json_encode($data);

Categories