How Do I Create a JSON Feed from a MongoDB Collection - php

I'm creating a CMS for my client to work with his photographs and to sell them on his site. For the CMS end as well as the front end, which both will be all AJAX, it'd be nice to get a JSON feed setup so that I can just use the same feed to generate new "pages" and "views" with JS.
So this example feed would have like {[name:'A Photo',description:'lorem ipsum...'],[...]} and then with jQuery or JS i can create a table of all his photographs, pages, etc. How can I set this up for myself?
Should I just create a PHP file that gets all the data from the MongoDB put's it in an array than convert the array to JSON?

$cursor = $this->collection->find($params);
$return = array();
$i=0;
while( $cursor->hasNext() )
{
$return[$i] = $cursor->getNext();
// key() function returns the records '_id'
$return[$i++]['_id'] = $cursor->key();
}
return json_encode($return);
That is how I return JSON frrom Mongo.

I did it this way:
$cursor = $collection->find($params);
if($cursor->hasNext())
{
return json_encode(iterator_to_array($cursor));
}
If you need the _ids, check this answer to see why you're not getting them:
MongoDB PHP: How do I get ObjectId with a JSON feed? (it's blank)

This is what I do :
$data = json_decode(json_encode(iterator_to_array($cursor, true)));
this way I make sure I have an array of objects that you can properly call :
foreach($data as $doc){
echo 'title:'.$doc->title.'<br>';
}

Related

How to extract data from this code (never seen this format before)?

I am using a plugin in my wordpress that stores my data in a specific way. I have a problem on how to extract that data into an array using php. The data currently saved in database is in this kind of format which i have never seen before. I want to get the name, price and the referral amount from this data.
I have tried using php foreach looping to extract data but it wont recognize the foreach function.
a:2:{i:0;a:4:s:4:"name";s:14:"Tower";s:2:"id";i:4177;s:5:"price";i:500;s:15:"referral_amount";s:3:"20";}i:1;a:4:s:4:"name";s:25:"Square";s:2:"id";i:3998;s:5:"price";i:178;s:15:"referral_amount";s:4:"87.4";}}
I wanted the array to store the data in this kind of way:
{
name:'Tower',
price:500,
referral_amount:20,
}
Does anyone knew how to extract this kind of data using php?
$data = 'a:2:{i:0;a:4:{s:4:"name";s:14:"Tower";s:2:"id";i:4177;s:5:"price";i:500;s:15:"referral_amount";s:3:"20";}i:1;a:4:{s:4:"name";s:25:"Square";s:2:"id";i:3998;s:5:"price";i:178;s:15:"referral_amount";s:4:"87.4";}}';
$data = preg_replace_callback('!s:(\d+):"(.*?)";!',
function ($match) {
return 's:'.strlen($match[2]).':"'.$match[2].'";';
},
$data);
$data_array = unserialize($data);
$final_data = json_encode($data_array);
echo $final_data;

Loading a Search and Retrieve via URL (SRU) in php with simplexml_load_string returns an empty object

Im trying to load search result from an library api using Search and Retrieve via URL (SRU) at : https://data.norge.no/data/bibsys/bibsys-bibliotekbase-bibliografiske-data-sru
If you see the search result links there, its looks pretty much like XML but when i try like i have before with xml using the code below, it just returns a empty object,
SimpleXMLElement {#546}
whats going on here?
My php function in my laravel project:
public function bokId($bokid) {
$apiUrl = "http://sru.bibsys.no/search/biblio?version=1.2&operation=searchRetrieve&startRecord=1&maximumRecords=10&query=ibsen&recordSchema=marcxchange";
$filename = "bok.xml";
$xmlfile = file_get_contents($apiUrl);
file_put_contents($filename, $xmlfile); // xml file is saved.
$fileXml = simplexml_load_string($xmlfile);
dd($fileXml);
}
If i do:
dd($xmlfile);
instead, it echoes out like this:
Making me very confused that i cannot get an object to work with. Code i present have worked fine before.
It may be that the data your being provided ha changed format, but the data is still there and you can still use it. The main problem with using something like dd() is that it doesn't work well with SimpleXMLElements, it tends to have it's own idea of what you want to see of what data there is.
In this case the namespaces are the usual problem. But if you look at the following code you can see a quick way of getting the data from a specific namespace, which you can then easily access as normal. In this code I use ->children("srw", true) to say fetch all child elements that are in the namespace srw (the second argument indicates that this is the prefix and not the URL)...
$apiUrl = "http://sru.bibsys.no/search/biblio?version=1.2&operation=searchRetrieve&startRecord=1&maximumRecords=10&query=ibsen&recordSchema=marcxchange";
$filename = "bok.xml";
$xmlfile = file_get_contents($apiUrl);
file_put_contents($filename, $xmlfile); // xml file is saved.
$fileXml = simplexml_load_string($xmlfile);
foreach ( $fileXml->children("srw", true)->records->record as $record) {
echo "recordIdentifier=".$record->recordIdentifier.PHP_EOL;
}
This outputs...
recordIdentifier=792012771
recordIdentifier=941956423
recordIdentifier=941956466
recordIdentifier=950546232
recordIdentifier=802109055
recordIdentifier=910941041
recordIdentifier=940589451
recordIdentifier=951721941
recordIdentifier=080703852
recordIdentifier=011800283
As I'm not sure which data you want to retrieve as the title, I just wanted to show the idea of how to fetch data when you have a list of possibilities. In this example I'm using XPath to look in each <srw:record> element and find the <marc:datafield tag="100"...> element and in that the <marc:subfield code="a"> element. This is done using //marc:datafield[#tag='100']/marc:subfield[#code='a']. You may need to adjust the #tag= bit to the datafield your after and the #code= to point to the subfield your after.
$fileXml = simplexml_load_string($xmlfile);
$fileXml->registerXPathNamespace("marc","info:lc/xmlns/marcxchange-v1");
foreach ( $fileXml->children("srw", true)->records->record as $record) {
echo "recordIdentifier=".$record->recordIdentifier.PHP_EOL;
$data = $record->xpath("//marc:datafield[#tag='100']/marc:subfield[#code='a']");
$subData=$data[0]->children("marc", true);
echo "Data=".(string)$data[0].PHP_EOL;
}

Trouble outputting json to php

One of my sources for data recently changed how they are providing a json file to me, they added something before the actual output, and I am having trouble getting the values to display on my landing page.
Old json output
string(6596) "[{"id":239,"solution_id":3486," etc...
New json output
string(6614) "{"picker_offers":[{"id":239,"solution_id":3486," etc...
For my landing page I am using the following:
$datastream = json_decode($result);
foreach($datastream as $component) {
$productid = $component->id;
I was able to successfully output the data to php from their old output, but I am not sure how to get around the value "picker_offers" that is being passed as part of the json file, but it isn't part of the actual data to output.
How can I not include that "picker_offers", or what can I do to be able to read the data? With this new output there is an extra curly bracket wrapper called "picker_offers" around the entire output.
Thank you very much
Solution 1 : if you want to remove picker_offers
$datastream = json_decode($result);
$picker_offers = $datastream->picker_offers;
unset($datastream->picker_offers);
$datastream = $picker_offers;
foreach($datastream as $component) {
$productid = $component->id;
}
Solution 2 : if you don't want to remove picker_offers
$datastream = json_decode($result);
foreach($datastream->picker_offers as $component) {
$productid = $component->id;
}

PHP foreach statement issue with accessing XML data

First, I am pretty clueless with PHP, so be kind! I am working on a site for an SPCA (I'm a Vet and a part time geek). The PHP accesses an xml file from a portal used to administer the shelter and store images, info. The file writes that xml data to JSON and then I use the JSON data in a handlebars template, etc. I am having a problem getting some data from the xml file to outprint to JSON.
The xml file is like this:
</DataFeedAnimal>
<AdditionalPhotoUrls>
<string>doc_73737.jpg</string>
<string>doc_74483.jpg</string>
<string>doc_74484.jpg</string>
</AdditionalPhotoUrls>
<PrimaryPhotoUrl>19427.jpg</PrimaryPhotoUrl>
<Sex>Male</Sex>
<Type>Cat</Type>
<YouTubeVideoUrls>
<string>http://www.youtube.com/watch?v=6EMT2s4n6Xc</string>
</YouTubeVideoUrls>
</DataFeedAnimal>
In the PHP file, written by a friend, the code is below, (just part of it), to access that XML data and write it to JSON:
<?php
$url = "http://eastbayspcapets.shelterbuddy.com/DataFeeds/AnimalsForAdoption.aspx";
if ($_GET["type"] == "found") {
$url = "http://eastbayspcapets.shelterbuddy.com/DataFeeds/foundanimals.aspx";
} else if ($_GET["type"] == "lost") {
$url = "http://eastbayspcapets.shelterbuddy.com/DataFeeds/lostanimals.aspx";
}
$response_xml_data = file_get_contents($url);
$xml = simplexml_load_string($response_xml_data);
$data = array();
foreach($xml->DataFeedAnimal as $animal)
{
$item = array();
$item['sex'] = (string)$animal->Sex;
$item['photo'] = (string)$animal->PrimaryPhotoUrl;
$item['videos'][] = (string)$animal->YouTubeVideoUrls;
$item['photos'][] = (string)$animal->PrimaryPhotoUrl;
foreach($animal->AdditionalPhotoUrls->string as $photo) {
$item['photos'][] = (string)$photo;
}
$item['videos'] = array();
$data[] = $item;
}
echo file_put_contents('../adopt.json', json_encode($data));
echo json_encode($data);
?>
The JSON output works well but I am unable to get 'videos' to write out to the JSON file as the 'photos' do. I just get '/n'!
Since the friend who helped with this is no longer around, I am stuck. I have tried similar code to the foreach statement for photos but am getting nowhere. Any help would be appreciated and the pets would appreciate it as well!
The trick with such implementations is to always look what you have got by dumping data structures to a log file or command line. Then to take a look at the documentation of the data you see. That way you know exactly what data you are working with and how to work with it ;-)
Here it turns out that the video URLs you are interested in are placed inside an object of type SimpleXMLElement with public properties, which is not really surprising if you look at the xml structure. The documentation of class SimpleXMLElement shows the method children() which iterates through all children. Just what we are looking for...
That means a clean implementation to access those sets should go along these lines:
foreach($animal->AdditionalPhotoUrls->children() as $photo) {
$item['photos'][] = (string)$photo;
}
foreach($animal->YouTubeVideoUrls->children() as $video) {
$item['videos'][] = (string)$video;
}
Take a look at this full and working example:
<?php
$response_xml_data = <<< EOT
<DataFeedAnimal>
<AdditionalPhotoUrls>
<string>doc_73737.jpg</string>
<string>doc_74483.jpg</string>
<string>doc_74484.jpg</string>
</AdditionalPhotoUrls>
<PrimaryPhotoUrl>19427.jpg</PrimaryPhotoUrl>
<Sex>Male</Sex>
<Type>Cat</Type>
<YouTubeVideoUrls>
<string>http://www.youtube.com/watch?v=6EMT2s4n6Xc</string>
<string>http://www.youtube.com/watch?v=hgfg83mKFnd</string>
</YouTubeVideoUrls>
</DataFeedAnimal>
EOT;
$animal = simplexml_load_string($response_xml_data);
$item = [];
$item['sex'] = (string)$animal->Sex;
$item['photo'] = (string)$animal->PrimaryPhotoUrl;
$item['photos'][] = (string)$animal->PrimaryPhotoUrl;
foreach($animal->AdditionalPhotoUrls->children() as $photo) {
$item['photos'][] = (string)$photo;
}
$item['videos'] = [];
foreach($animal->YouTubeVideoUrls->children() as $video) {
$item['videos'][] = (string)$video;
}
echo json_encode($item);
The obvious output of this is:
{
"sex":"Male",
"photo":"19427.jpg",
"photos" ["19427.jpg","doc_73737.jpg","doc_74483.jpg","doc_74484.jpg"],
"videos":["http:\/\/www.youtube.com\/watch?v=6EMT2s4n6Xc","http:\/\/www.youtube.com\/watch?v=hgfg83mKFnd"]
}
I would however like to add a short hint:
In m eyes it is questionable to convert such structured information into an associative array. Why? Why not a simple json_encode($animal)? The structure is perfectly fine and should be easy to work with! The output of that would be:
{
"AdditionalPhotoUrls":{
"string":[
"doc_73737.jpg",
"doc_74483.jpg",
"doc_74484.jpg"
]
},
"PrimaryPhotoUrl":"19427.jpg",
"Sex":"Male",
"Type":"Cat",
"YouTubeVideoUrls":{
"string":[
"http:\/\/www.youtube.com\/watch?v=6EMT2s4n6Xc",
"http:\/\/www.youtube.com\/watch?v=hgfg83mKFnd"
]
}
}
That structure describes objects (items with an inner structure, enclosed in json by {...}), not just arbitrary arrays (sets without a structure, enclosed in json by a [...]). Arrays are only used for the two unstructured sets of strings in there: photos and videos. This is much more logical, once you think about it...
Assuming the XML Data and the JSON data are intended to have the same structure. I would take a look at this: PHP convert XML to JSON
You may not need for loops at all.

Searching within JSON with PHP for server side implementation of autocomplete jQuery plugin

I am trying to use jQuery Autocomplete Plugin in my PHP web application.
I have a JSON file on the server that has the data for the search. It looks like this:
{
"_E161": {
"keggId":"rn:R05223",
"abbrev":"ADOCBLS",
"name":"Adenosylcobalamin 5'-phosphate synthase",
"equation":"agdpcbi[c] + rdmbzi[c] -> h[c] + adocbl[c] + gmp[c] ",
},
"_E163": {
....
}
}
I would like to go through this JSON file (has 3500 entries) with PHP script that gets search term from the jQuery autocomplete plugin. Then return the entries that contain search term back to client side to populate autocomplete.
What would be a better way to implement this? My first guess is to loop through the JSON file and use strpos() But I suspect that might be slow?
You can make use on preg_grep (Return array entries that match the pattern),
// sanitize, and perform some processing to ensure is a valid regex pattern
$pattern = ...;
$json = json_decode( ... );
$arr = array();
foreach ($json as $key=>$arr)
{
$arr[$key] = $arr['name'];
}
$matches = preg_grep("/$pattern/i", $arr);
// $matches will hold the matches
// and you refer back to the $json using associate key

Categories