I found this site, that provides IMDB API:
http://www.omdbapi.com
and for getting for example the hobbit's it's easy enough as this:
http://www.omdbapi.com/?i=tt0903624
Then I get all this information:
{"Title":"The Hobbit: An Unexpected Journey","Year":"2012","Rated":"11","Released":"14 Dec 2012","Runtime":"2 h 46 min","Genre":"Adventure, Fantasy","Director":"Peter Jackson","Writer":"Fran Walsh, Philippa Boyens","Actors":"Martin Freeman, Ian McKellen, Richard Armitage, Andy Serkis","Plot":"A curious Hobbit, Bilbo Baggins, journeys to the Lonely Mountain with a vigorous group of Dwarves to reclaim a treasure stolen from them by the dragon Smaug.","Poster":"http://ia.media-imdb.com/images/M/MV5BMTkzMTUwMDAyMl5BMl5BanBnXkFtZTcwMDIwMTQ1OA##._V1_SX300.jpg","imdbRating":"9.2","imdbVotes":"5,666","imdbID":"tt0903624","Response":"True"}
The thing is that I only want for exmaple the title, the year and the plot information, and I wonder how I can only retrieve this.
I want to use PHP.
Here you go... simply decode the json, and pull out the data you need. If need be, you can re-encode it as json afterwards.
$data = file_get_contents('http://www.omdbapi.com/?i=tt0903624');
$data = json_decode($data, true);
$data = array('Title' => $data['Title'], 'Plot' => $data['Plot']);
$data = json_encode($data);
print($data);
Another way to do this (slightly more efficiently) is to unset unneeded keys, e.g.:
$data = file_get_contents('http://www.omdbapi.com/?i=tt0903624');
$data = json_decode($data, true);
$keys = array_keys($data);
foreach ($keys as $key) {
if ($key != 'Title' && $key != 'Plot) {
unset($data[$key]);
}
}
$data = json_encode($data);
print($data);
OMDBAPI.com is no longer free to use. As you can read on their website:
05/08/17 - Going Private! Please go read the post on the Patreon page about this major change.
This means you must become a donator to get access to the API. I used their API for over a year and now it stopped. If you need to perform lots of queries then I think becoming a sponsor to OMDBAPI is a good idea. However I used their API in my little private project. After googling a bit I found another API. Here's the code you can use:
<?php
$imdbID = 'tt2866360';
$data = json_decode(file_get_contents('http://api.rest7.com/v1/movie_info.php?imdb=' . $imdbID));
if (#$data->success !== 1)
{
die('Failed');
}
echo '<pre>';
print_r($data->movies[0]);
I am not affiliated with this website. But I use this API so can answer a question or two if anyone has.
Related
PHP Version 7.4
I am currently working on a small php program to take certain shipments and optimize the order of them to the most efficient route. So far so good, it works with the google maps api the following way:
$url = "https://maps.googleapis.com/maps/api/directions/json?";
$url .= "origin=".urlencode($this->startPoint);
$url .= "&destination=".urlencode($this->endPoint);
$url .= "&waypoints=".urlencode("optimize:true")."|";
$x = 0;
foreach($ordersadress as $order){
if($x != 0){
$url .= urlencode("|");
}
$url .= urlencode($order["address"]);
$x++;
}
$url .= "&key=".$conf->global->GOOGLE_MAPS_API_KEY;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resp = curl_exec($ch);
$json = json_decode($resp);
Now, in order to know which Shipment actually comes first, I go through the json response and compare the addresses of my shipments to each waypoint in the response to see which address comes first and so on.
Here is my problem, in the response the addresses are not written out, they are shortened. For example with a german address, my shipment address that I add to the api call is "Kirchenplatz 4". In googles response they shorten it to "Kirchenpl. 4".
I think the equivalent in english would be changing "Road" to "Rd".
(I will put an example request at the end, incase you do not know what it looks like, you do need a Google API key though.)
For now, I'm doing it the following way:
foreach($json->routes[0]->legs as $leg){
if($iterator != 0){
foreach($ordersadress as $order){
$addy = explode(",", $leg->start_address);
$oa = explode(",", $order["address"]);
//Here I compare if the returned address is the same as the one on the shipment, needs to be a 1:1 match, this is my issue
if(strpos($oa[0], $addy[0]) !== false){
$lat = $leg->start_location->lat;
$lon = $leg->start_location->lng;
$co = $order["object"];
$this->orders[] = ["rowid" => $co->id, "sortorder" => $sortnum, "notes" => "", "tourdate" => $tourdate->format("d.m.Y"), "address" => $leg->start_address, "drivetime" => $leg->duration->value, "object" => $co, "lat" => $lat, "lon" => $lon];
$this->kmAll += round($leg->distance->value/1000, 2);
$sortnum++;
foreach($leg->steps as $step){
$polyline .= $step->polyline->points;
}
break;
}
}
unset($order);
}
This example only works with exact 1:1 matches, which is ofcourse not viable in a real world scenario, as the workers of my customer will not be able to always put the address in the exact same way that google returns it, besides, there is already data for thousands of shipments which would have to be changed.
I have thought of following solutions:
Get a list of all words that are shortened by google, and then do it to my addresses. However I was not able to find a list.
My second solution was to do a percentage match of 2 addresses, and the one with the highest match would be at the position that google returned. With this solution, I am going to be honest I did not really understand the similar_text function and how it works and I am not sure if it would even be a good solution in my case.
I am open to any ideas and suggestions that you might have.
Example Google API request:
https://maps.googleapis.com/maps/api/directions/json?origin=Lange+G.+20%2C+2700+Wiener+Neustadt&destination=Ruckergasse+42%2C+1120+Wien&waypoints=optimize%3Atrue|Brauhausgasse+6%7CHauptpl.+1%2C+Graz%7CKirchenpl.+4%2C+G%C3%A4nserndorf%7CS%C3%BCdtiroler+Pl.+1%2C+Salzburg%7CUnter+dem+Rucker+14%7CVivenotgasse+3%2F6+13%2C+Wien&key=YOUR_API_KEY
After trying for a while and asking some friends I arrived at the solution of using the fuzzy logic to match addresses. Luckily there is already an implementation of a method of this logic which is called levenshtein($string1, $string2)
I would suggest reading it up here: https://www.php.net/manual/de/function.levenshtein.php
Example 1 was basically my solution to the problem and has been working without problems so far.
However be careful! As explained here in the comment below example 1 using UTF-8 will cause problems!
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.
I want to make a personal profile page for my Starcraft 2 Clan with the API in PHP.
The normal stats are working for me.
$json = file_get_contents('http://eu.battle.net/api/sc2/profile/3077083/1/gbot/');
$obj = json_decode($json);
echo $obj->displayName;
However when I'll want to use the ladder stats I can't even display one variable.
$json = file_get_contents('
http://eu.battle.net/api/sc2/profile/3077083/1/gbot/ladders?locale=en_GB');
$lad = json_decode($json);
So how can I display the stats from the child with HOTS_SOLO in it?
This is just basic array access?
$json = file_get_contents('http://eu.battle.net/api/sc2/profile/3077083/1/gbot/ladders?locale=en_GB');
$data= json_decode($json);
$currentSeason = $data->currentSeason;
foreach ($currentSeason as $obj) {
foreach ($obj->ladder as $ladder) {
if ($ladder->matchMakingQueue == 'HOTS_SOLO') {
// this is the ladder we want to display
echo $ladder->ladderName; // Tychus Theta
}
}
}
There appears to be a newline in your URL (it starts on one line, where the whole literal begins on the line before). The file_get_contents() may be failing.
If that's not the problem, then it's something more subtle. Firefox/Chrome don't seem to have a problem with it. If json_decode is choking, it might be a forgiveable syntax issue. Try saving the data locally, and then removing components until it parses, and see if you can then do a string-replace or something to fix it, going forward.
I just wanted some input about my use of JSON.
<?php
header('Content-Type: text/plain');
//results
$results = array();
for($i=0;$i<20;$i++)
{
$result = array();
$result['name'] = 'Test Season '.ceil(($i+1)/13).' Episode '.(($i%13)+1);
//$result['torrent'] = 'https://www.example.com/?id='.$i.'&key='.uniqid();
$result['torrents'] = array();
$c = mt_rand(1,4);
for($j=0;$j<$c;$j++)
{
$torrent = array();
$torrent['url'] = 'https://www.example.com/?id='.uniqid().'&key='.md5(uniqid());
$torrent['codec'] = $j%2 == 0 ? 'xvid' : 'h264';
$torrent['resolution'] = '720p';
$result['torrents'][] = $torrent;
}
$results[] = $result; //push
}
echo json_encode($results);
?>
This is just some test code, not an actual implementation. Am I using JSON correctly and too the fullest? Or is some better method of doing this?
I have legal torrents that I'd like to do some JSON with.
Torrents are grouped by name which contain multiple torrents (actual links to data). And other information such as codec etc.
This is my first time actually outputting JSON, would XML be better?
Are there any guides on this topic (hopefully not entire books)?
Thanks.
What you doing is right. I like to use the StdClass to make objects rather than key value arrays, just cause it looks sexier! E.g.
$torrent = new StdClass();
$torrent->url = 'https://www.example.com/?id='.uniqid().'&key='.md5(uniqid());
$torrent->codec = $j%2 == 0 ? 'xvid' : 'h264';
$torrent->resolution = '720p';
$result['torrents'][] = $torrent;
As you say you don't need to read a whole book on the matter, I would have a look here http://php.net/manual/en/book.json.php to get to grips with the basics of JSON.
In terms of JSON vs XML, I find it far easier to represent data as JSON as it is easier to fetch the specific data you want much in the same way you can access the info in a stdClass object.
[EDIT]
And as Stefan Gehrig says make sure you define your content type as "application/json".
Absolutely fine. You could only change the MIME type to be RFC 4627 compliant though: application/json.
Below is the XML I am working with - there are more items - this is the first set. How can I get these elements in to an array? I have been trying with PHP's SimpleXML etc. but I just cant do it.
<response xmlns:lf="http://api.lemonfree.com/ns/1.0">
<lf:request_type>listing</lf:request_type>
<lf:response_code>0</lf:response_code>
<lf:result type="listing" count="10">
<lf:item id="56832429">
<lf:attr name="title">Used 2005 Ford Mustang V6 Deluxe</lf:attr>
<lf:attr name="year">2005</lf:attr>
<lf:attr name="make">FORD</lf:attr>
<lf:attr name="model">MUSTANG</lf:attr>
<lf:attr name="vin">1ZVFT80N555169501</lf:attr>
<lf:attr name="price">12987</lf:attr>
<lf:attr name="mileage">42242</lf:attr>
<lf:attr name="auction">no</lf:attr>
<lf:attr name="city">Grand Rapids</lf:attr>
<lf:attr name="state">Michigan</lf:attr>
<lf:attr name="image">http://www.lemonfree.com/images/stock_images/thumbnails/2005_38_557_80.jpg</lf:attr>
<lf:attr name="link">http://www.lemonfree.com/56832429.html</lf:attr>
</lf:item>
<!-- more items -->
</lf:result>
</response>
Thanks guys
EDIT: I want the first items data in easy to access variables, I've been struggling for a couple of days to get SimpleXML to work as I am new to PHP, so I thought manipulating an array is easier to do.
Why do you want them in an array? They are structured already, use them as XML directly.
There is SimpleXML and DOMDocument, now it depends on what you want to do with the data (you failed to mention that) which one serves you better. Expand your question to get code samples.
EDIT: Here is an example of how you could handle your document with SimpleXML:
$url = "http://api.lemonfree.com/listings?key=xxxx&make=ford&model=mustang";
$ns_lf = "http://api.lemonfree.com/ns/1.0";
$response = simplexml_load_file($url);
// children() fetches all nodes of a given namespace
$result = $response->children($ns_lf)->result;
// dump the entire <lf:result> to see what it looks like
print_r($result);
// once the namespace was handled, you can go on normally (-> syntax)
foreach ($result->item as $item) {
$title = $item->xpath("lf:attr[#name='title']");
$state = $item->xpath("lf:attr[#name='state']");
// xpath() always returns an array of matches, hence the [0]
echo( $title[0].", ".$state[0] );
}
Perhaps you should look at SimplePie, it parses XML feeds into an array or an object (well, one of the two :D). I think it works well for namespaces and attributes too.
Some benefits include it's GPL license (it's free) and it's support community.
SimpleXML is the best way to read/write XML files. Usually it's as easy as using arrays, except in your case because there's XML namespaces involved and it complicates stuff. Also, the format used to stored attributes kind of sucks, so instead of being easy to use and obvious it's kind of complicated, so here's what you're looking for so that you can move on to doing something more interesting for you:
$response = simplexml_load_file($url);
$items = array();
foreach ($response->xpath('//lf:item') as $item)
{
$id = (string) $item['id'];
foreach ($item->xpath('lf:attr') as $attr)
{
$name = (string) $attr['name'];
$items[$id][$name] = (string) $attr;
}
}
You'll have everything you need in the $items array, use print_r() to see what's inside. $url should be the URL of that lemonfree API thing. The code assumes there can't be multiple values for one attribute (e.g. multiple images.)
Good luck.
This is the way I parsed XML returned from a clients email address book system into an array so I could use it on a page. uses an XML parser that is part of PHP, I think.
here's it's documentation http://www.php.net/manual/en/ref.xml.php
$user_info = YOUR_XML
SETS $xml_array AS ARRAY
$xml_array = array();
// SETS UP XML PARSER AND PARSES $user_info INTO AN ARRAY
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $user_info, $values, $index);
xml_parser_free($xml_parser);
foreach($values as $key => $value)
{
// $value['level'] relates to the nesting level of a tag, x will need to be a number
if($value['level']==x)
{
$tag_name = $value['tag'];
// INSERTS DETAILS INTO ARRAY $contact_array SETTING KEY = $tag_name VALUE = value for that tag
$xml_array[strtolower($tag_name)] = $value['value'];
}
}
If you var_dump($values) you should see what level the data you're info is on, I think it'll be 4 for the above XML, so you can then filter out anything you don't want by changing the value of $value['level']==x to the required level, ie. $value['level']==4.
This should return $xml_array as an array with $xml_array['title'] = 'Used 2005 Ford Mustang V6 Deluxe' etc.
Hope that helps some