json-decode two feed sources - php

I am try to decode two different json feed urls and merge into one oject/output. I have tried the below, however, not really having much luck.
feed source 1: http://sourcesample.com/feed/posts
data: [
{
name: "Me",
url: "http://example.com/sample",
title: "Sample Title",
}
]
feed source 2: http://differentsource.com/feed/details
data: [
{
likes: "200",
shares: "300",
total: "1000",
}
]
$sources =array("http://sourcesample.com/feed/posts", "http://differentsource.com/feed/details");
$requests = file_get_contents($sources[0],$sources[1]);
$response = json_decode($requests);
foreach($response->data as $item){
echo'<li>'.$item->name.'</li><li>'.$item->shares.'</li>'
Printing the name works, but when trying to print the second object feed, nothing. Any ideas?

file_get_contents() won't return more than one URL's contents at a time. The second parameter is being treated as true, roughly, for the use_include_path parameter. For your purposes, it's irrelevant.
Anyway, only the first feed is read. It includes no "shares" data.
Even if both were read, the result would be:
'data: [
{
name: "Me",
url: "http://example.com/sample",
title: "Sample Title",
}
]
data: [
{
likes: "200",
shares: "300",
total: "1000",
}
]'
which is not a valid JSON string - it's two objects next to each other, not merged.
If you're really confident that both feeds are the same size, you can read them both (separately) then loop through them at once:
$names = json_decode( file_get_contents( $sources[0] ) );
$stats = json_decode( file_get_contents( $sources[1] ) );
for ( $i = 0; $i < count( $names->data ); ++$i )
{
$name = $names->data[$i];
$stat = $stats->data[$i];
echo '<li>' . htmlspecialchars($name->name) . '</li><li>' .
htmlspecialchars($stat->shares) . '</li>';
}

Related

Merge two JSONs php

I have 2 different jsons and I need to get one inside the other.
JSON 1
[{
"id":"1",
"texto":"Vamos newells 17471934",
"fecha":"2019-06-24 12:09:12",
"categoria":"1",
"idpayment":"Reference_1561388952",
"provincia":"1",
"estado":"NO",
"email":"newells#gmail.com"
}]
JSON 2
{
"Texto": " VENDO O PERMUTO",
"imageJob": {
"pathConvertido": "ClasificadosPNG/0011311247.png",
"convertido": true,
"id": 5011
},
"rubroClasificado": {
"CodigoRubro": 150,
"id": 76
}
}
I need the second one inside the first one for use with javascript
I tried the array_merge() php function without getting results
since JSON1 is an array of JSON-object and JSON2 is just a JSON-object.
in addition to that you said, 'I need the second one inside the first one for use with javascript'. therefore, you can test this code https://3v4l.org/1HGNF/perf#output
please compare all performances in mem-usage and timing
$j1 = '[{
"id":"1",
"texto":"Vamos newells 17471934",
"fecha":"2019-06-24 12:09:12",
"categoria":"1",
"idpayment":"Reference_1561388952",
"provincia":"1",
"estado":"NO",
"email":"newells#gmail.com"
}]';
$j2 = '{
"Texto": " VENDO O PERMUTO",
"imageJob": {
"pathConvertido": "ClasificadosPNG/0011311247.png",
"convertido": true,
"id": 5011
},
"rubroClasificado": {
"CodigoRubro": 150,
"id": 76
}
}';
$j1 = json_decode($j1, true);
$j2 = json_decode($j2, true);
$j1[] = $j2;
var_dump(json_encode($j1));
You can use json_decode with parameter true to convert JSON into an array , then use array_merge to make them a single array
$j1 = '[{"id":"1","texto":"Vamos newells 17471934","fecha":"2019-06-24 12:09:12","categoria":"1","idpayment":"Reference_1561388952","provincia":"1","estado":"NO","email":"newells#gmail.com"}]';
$j1arr = json_decode($j1, true);
$j2 = ' {
"Texto": " VENDO O PERMUTO",
"imageJob": {
"pathConvertido": "ClasificadosPNG/0011311247.png",
"convertido": true,
"id": 5011
},
"rubroClasificado": {
"CodigoRubro": 150,
"id": 76
}
}';
$j2arr = json_decode($j2, true);
$r = array_merge($j1arr[0], $j2arr);
You can use the merged array in javascript by using json_encode
json_encode($r)
https://3v4l.org/WKX1U
Do it simply like this way without any extra array merging methods-
<?php
$json1 = json_decode('[{"id":"1","texto":"Vamos newells 17471934","fecha":"2019-06-24 12:09:12","categoria":"1","idpayment":"Reference_1561388952","provincia":"1","estado":"NO","email":"newells#gmail.com"}]',1);
$json2 = json_decode('{"Texto":" VENDO O PERMUTO","imageJob":{"pathConvertido":"ClasificadosPNG/0011311247.png","convertido":true,"id":5011},"rubroClasificado":{"CodigoRubro":150,"id":76}}',1);
$json1[] = $json2; // add second json to first json
print_r($json1);
echo json_encode($json1);
?>
WORKING DEMO: https://3v4l.org/qhsJq
As you said you want to process the resulting data in JavaScript, and as per your question you want second json inside the first json. You can do something like this.
You will get a json as final result.
$first = '[{
"id":"1",
"texto":"Vamos newells 17471934",
"fecha":"2019-06-24 12:09:12",
"categoria":"1",
"idpayment":"Reference_1561388952",
"provincia":"1",
"estado":"NO",
"email":"newells#gmail.com"
}]';
$first = str_replace(['[',']','}'], '', $first);
$second = '{
"Texto": " VENDO O PERMUTO",
"imageJob": {
"pathConvertido": "ClasificadosPNG/0011311247.png",
"convertido": true,
"id": 5011
},
"rubroClasificado": {
"CodigoRubro": 150,
"id": 76
}
}';
$second = preg_replace('/\{/', ',', $second,1);
print_r($first.$second);
As result you will get a valid json, second json inside your first json, you can validate here

Decoding JSON SubArray PHP

I have looked around on Google for quite some time now, and I'm unable to find a solution that works for me.
I have this JSON Array:
[
{
"id": 1000,
"userIdent": "ABC1000",
"username": "john.doe",
"contacts": [
{
"id": 2000,
"clientId": 1000,
"email": "john.doe#example.com",
"phone": "",
"name": "",
"isBilling": false,
"isContact": false,
"types": [
{
"id": 3000,
"name": "Home contact"
}
]
}
]
}
]
and I have this PHP code:
$json = json_decode($response, true);
foreach($json as $item) {
echo $item['id'] . "<br>";
echo $item['userIdent'] . "<br>";
echo $item['contacts']['phone'] . "<br><br>";
foreach($json->contacts as $contacts) {
echo $contacts->phone;
echo $contacts['contacts']['phone'];
}
}
I have tried:
$item['contacts']['phone'];
$contacts->phone;
$contacts['contacts']['phone'];
I can't seem to be able to full any of the data from the sub-array "contacts". Any help would be greatly appreciated!
Note:- When you use true while using json_decode() it converts all json data to array(inner or outer). So you need to treat contacts as an array not an object.
So You need to iterate over $item['contacts'] array in the second foreach()
Do like below:-
$json = json_decode($response, true);
foreach($json as $item) {
echo $item['id'] . "<br>";
echo $item['userIdent'] . "<br>";
foreach($item['contacts'] as $contacts) {//treat contacts as an array not as an object
echo $contacts['phone'];
}
}
Output:- https://eval.in/952121 (i have taken phone number for testing purpose)
You have made a mistake, on your json, the contacts property is an array, so you can't access it (either in javascript or php) as an object with $contacts->contacts['phone'].
You should do something like that : $contacts->contacts[0]['phone'] or iterate other each contacts if there may be many.
Your code should look more like this
foreach($json as $item) { // 1
echo $item['id'] . "<br>";
echo $item['userIdent'] . "<br>";
foreach($item['contacts'] as $contact) { // 2
echo $contact['phone'];
}
}
So in the first foreach you start iterating over you entire array of items (1). Inside an item is an array contacts, so you start iterating over that with a new foreach (2). Each contact can be accessed directly inside the inner foreach.
Also, on decoding you said you wanted an array as output, so you should expect that and always access it like an array (square braces). If you would have gone for an object, the $contacts->phone syntax would work, but you shouldn't mix them like you are doing.
I hope this makes sense. Feel free to ask if not.

creating valid json data in Laravel

When a new User is created, I save the username and password (no hashed) in a json file as well as in the DB, so every time I'm appending new users to the json file:
{
"user3": "demo"
} {
"user4": "demo"
} {
"user4": "demo"
} {
"user5": "demo"
}
the code:
$data = array($request->input('username') => $request->input('password'));
$datos = json_encode($data);
File::append(storage_path('archivos/datos.json'), $data);
of course the format above isn't valid json, how could i get this
[{
"user3": "demo"
}, {
"user4": "demo"
}, {
"user4": "demo"
}, {
"user5": "demo"
}, {
"user5": "demo"
}, {
"user5": "demo"
}, {
"user7": "demo"
}, {
"user8": "demo"
}]
and read it using foreach like this:
$result = File::get(storage_path('archivos/datos.json'));
$result = json_decode($result);
foreach($result as $key=>$item){
echo $key .''. $item;
}
First get the string from file then you can do a str_replace all "} {" with "} , {" a json also have [ at the start and ] at the end so we add them too:
$json = "[".str_replace('} {', '},{', $fileContent)."]";
Here we have a json string in $json variable so we can convert it to array by this:
$users = json_decode($json);
the fastest way would be to append some data:
fopen('myfile.json', 'a');
but you want to store an array, so you have to read the content of the file, update it and save it.
$users = json_decode(file_get_content(storage_path('archivos/datos.json')));
$users[] = $newUser;
file_put_contents(storage_path('archivos/datos.json'), json_encode($users, JSON_PRETTY_PRINT);
you can also make a one-liner (ugly, but works):
file_put_contents(storage_path('archivos/datos.json'), json_encode(json_decode(file_get_content(storage_path('archivos/datos.json')))[] = $newUser, JSON_PRETTY_PRINT);

Parse Nested JSON with PHP

I've look high and low for a solution for this, but haven't found anything that is exactly what I am running into. I am using php to parse a JSON response that is nested in a way that makes it difficult to extract specific fields.
Here is a bit of the JSON:
{
"collection":{
"items":[
{
"href":"https://api.teamsnap.com/v3/members/MEMBERID",
"data":[
"name":"id",
"value": 0000000 // MEMBERID
},
{
"name":"type",
"value":"member"
},
{
"name":"address_city",
"value":""
},
{
"name":"address_state",
"value":""
},
Here is my php:
$json = file_get_contents($url, false, $context);
$result = json_decode($json);
foreach ($result->collection->items as $items=>$val) {
foreach ($val->data as $data=>$datasets) {
foreach ($datasets as $dataset=>$val) {
echo $dataset.': '.$val;
echo "<br>";
}
}
};
and this is a bit of the current output:
name: id
value: MEMBERID
name: first_name
value: MEMBERNAME
name: last_name
value: MEMBERNAME
what I want to do is be able to list all of the members in this response with their first and last name. I have tried using $val->first_name, $val['first_name']; and such but all result in a foreach error.
If you can ensure every data member has a name and value field you can use something like this and skip a for-loop:
$json = file_get_contents($url, false, $context);
$result = json_decode($json);
foreach ($result->collection->items as $itemKey => $val) {
$data = array();
foreach ($val->data as $dataKey => $dataset) {
$data[$dataset->name] = $dataset->value;
}
var_dump($data);
};
Although you should probably check for $result->collection and $result->collection->items first before looping over them to avoid errors.

How to loop over and access various elements in an array that is both multidimentional and associative? PHP, either JSON or XML

I'm retrieving bibliographic data via an API (zotero.org), and it is similar to the sample at the bottom (just way more convoluted - sample is typed).
I want to retrieve one or more records and display certain values on the page. For example, I would like to loop through each top level record and print the data in a nicely formated citation. Ignoring the proper bib styles for the moment, let's say I want to just print out the following for each record returned:
author1 name, author2 name, article title, publication title, key
This doesn't match the code, because I've clearly been referencing the key value pairs incorrectly and will just make a mess of it.
The following is laid out like the data if I request JSON format, though I can request XML data instead. I'm not picky; I've tried using each with no luck.
[
{
"key": "123456",
"state": 100,
"data": {
"articleTitle": "Wombat coprogenetics: enumerating a common wombat population by microsatellite analysis of faecal DNA",
"authors": [
{
"firstName": "Sam C.",
"lastName": "Smith"
},
{
"firstName": "Maxine P.",
"lastName": "Jones"
}
],
"pubTitle": "Australian Journal of Zoology",
"tags": [
{
"tag": "scary"
},
{
"tag": "secret rulers of the world"
}
]
}
},
{
"key": "001122",
"state": 100,
"data": {
"articleTitle": "WOMBAT and WOMBAT-PK: Bioactivity Databases for Lead and Drug Discovery",
"authors": [
{
"firstName": "Marius",
"lastName": "Damstra"
}
],
"pubTitle": "Chemical Biology: From Small Molecules to Systems Biology",
"tags": [
{
"tag": "Wrong Wombat"
}
]
}
}
]
If there is a mistake in brackets, commas, etc. it is just a typo in my example and not the cause of my issue.
decode your json as array and iterate it as any array as flowing:
$json_decoded= json_decode($json,true);
$tab="\t";
foreach ($json_decoded as $key => $val) {
echo "Article ".$val["key"]."\n" ;
echo $tab."Authors :\n";
foreach ($val["data"]["authors"] as $key => $author){
echo $tab.$tab. ($key+1) ." - ".$author["firstName"]. " ".$author["lastName"]."\n";
}
echo $tab."Article Title: ".$val["data"]["articleTitle"] ."\n";
echo $tab."Publication Title: ".$val["data"]["pubTitle"] ."\n";
echo $tab."Key: ".$val["key"]."\n";
}
run on codepad
and you can use the same method for xml as flowing:
$xml = simplexml_load_string($xmlstring);
$json = json_encode($xml);
$json_decoded = json_decode($json,TRUE);
//the rest is same
for xml you can use the SimpleXml's functions
or DOMDocument class
Tip
to know the structure of your data that api return to you after it converted to array use var_dump($your_decoded_json) in debuging
Something like this might be a good start for you:
$output = [];
// Loop through each entry
foreach ($data as $row) {
// Get the "data" block
$entry = $row['data'];
// Start your temporary array
$each = [
'article title' => $entry['articleTitle'],
'publication title' => $entry['pubTitle'],
'key' => $row['key']
];
// Get each author's name
foreach ($entry['authors'] as $i => $author) {
$each['author' . ++$i . ' name'] = $author['firstName'] . ' ' . $author['lastName'];
}
// Append it to your output array
$output[] = $each;
}
print_r($output);
Example: https://eval.in/369313
Have you tried to use array_map ?
That would be something like:
$entries = json_decode($json, true);
print_r(array_map(function ($entry) {
return implode(', ', array_map(function ($author) {
return $author['firstName'];
}, $entry['data']['authors'])) . ', ' . $entry['data']['articleTitle'] . ', ' . $entry['key'];
}, $entries));

Categories