I make an API call which return a list of items. I use a foreach loop to iterate the JSON data:
foreach($decoded_results['items'] as $item) {
$image_link = $item['thumb'];
$link_url = $item['url'];
$subject = $item['title'];
}
I need some additional information for each item and in order to get that I need to call another endpoint.
In my first response every item in the JSON object has a property with an ID that corresponds to a property with the same ID in the other JSON object, that I get as a response when I call the second endpoint. This ID is needed as a parameter in the query string for the second API call.
What would be the best approach to accomplish this? I've looked into curl_multi a little bit but not sure if this is suitable for the situation.
The best solution would be if your second API has an endpoint that accepts a list of IDs and can return all the information you need in one call, otherwise it is known as the N+1 problem in database management, it is also the same here and is not an optimal solution.
Related
I'm just looking at the Microsoft Graph API PHP SDK to get a bunch of resources, notably Users.
Looking a the SDK docs, there's 2 ways to get users, one using the createRequest() method and the other using the createCollectionRequest() method.
The docs suggests using the createCollectionRequest() and then just doing a while loop, array_merge and getPage() to create an array.
while (!$docGrabber->isEnd()) {
$docs = array_merge($docs,$docGrabber->getPage());
}
The issue is, I have a collection of ~50,000 users, so this method isn't particularly efficient.
I guess the biggest issue, i that the above example (using the while loop) is to avoid using the #odata.nextLink that the API returns.
But, what if we actually want to use this, instead of returning every single record in a single array?
Thanks
Instead of using getPage() and that sample, you can access the nextlink with something like this:
$url = "/users";
// Get the first page
$response = $graph->createCollectionRequest("GET", $url)
->setPageSize(50)
->execute();
if ($response->getNextLink())
{
$url = $response->getNextLink();
// TODO: remove https://graph.microsoft.com/v1.0 part of nextlink
} else {
// There are no more pages.
return null;
}
// get the next page, page size is already set in the next link
$response = $graph->createCollectionRequest("GET", $url)
->execute();
I am using open api given by course era.
Problem is that its giving only list of 100 courses,i checked on website there are 1294 courses listed.then why it is giving 100 courses on request.
my code is
<?php
$url = "https://api.coursera.org/api/courses.v1";
$result = file_get_contents($url);
print_r($result);
?>
what should i do to fetch whole course catalog and store it in mysql db
From their docs:
https://building.coursera.org/app-platform/catalog/
To paginate through a result set, use integer start and limit query
parameters.
curl "https://api.coursera.org/api/courses.v1?start=300&limit=10"
So just use start and limit for pagination
The API will only return 100 records on each call. In order to get all records, you will need to call the method multiple times and concatenate/store all of the responses.
The response returns the following value, which can be used to modify the subsequent call.
paging":{"next":"101","total":1948},"linked":{}}
Which can then be used accordingly;
https://api.coursera.org/api/courses.v1?start=101
From the documentation:
curl "https://api.coursera.org/api/courses.v1?start=300&limit=10"
You will need to loop through and increase the start until you do not get any more results.
Documentation
I have been building a test app that gathers pictures and certain pieces of user information from Instagram (only using PHP). I am not using the official API, but instead parsing the JSON response that I get from the url.
I'm trying to gather comments for a certain post. The issue is that when there's more than one comment, I can see the text for each comment, but the object name in the response is the same (it repeats for every comment): {text}.
Here's an abbreviated example response:
{"text":"I think this is funded by my company","created_at"...,"user":{"username"...}, blah blah blah},
{"text":"Very cool","created_at"...,"user":{"username"...blah blah blah
As you can see, for each comment made, there is a "text" object that I need to grab.
Here is my function (shortened) that parses the JSON and gets the comment text:
function scrape_insta_user_post($postid) {
$insta_source = file_get_contents('https://www.instagram.com/p/'.$postid.'/');
$shards = explode('window._sharedData = ', $insta_source);
$insta_json = explode(';</script>', $shards[1]);
$insta_array = json_decode($insta_json[0], TRUE);
global $the_pic_comments;
$the_pic_comments = $insta_array['entry_data']['PostPage'][0]['media']['comments']['nodes'][0]['text'];
}
I have another function that I use to display $the_pic_comments by simply echoing the results.
echo $the_pic_comments;
In cases where there is more than one {text} object, how would I go about displaying each comment? I'm assuming some kind of foreach() loop might work, but I can't get the foreach() to work with my json_decode() function.
This currently works, but only displays one comment, and everything else is ignored.
Can you help me create a loop that will get each comment from the JSON response?
Thanks!
Judging from your code alone, it seems that it should be:
foreach ($insta_array['entry_data']['PostPage'][0]['media']['comments']['nodes'] as $comment) {
echo $comment['text']; // Or add to array, eg. $comments[] = $comment['text'];
}
Note that since you are not using official API, your mechanism may break any time without notice shall Instagram change anything in their code.
I need to get the state and country from the visitor IP. I will be using the country info to showcase custom made products. As for the state info it will not be used for the same purpose but only for record keeping to track the demand.
I have found on this site an instance of using the ipinfo.io API with this example code:
function ip_details($ip) {
$json = file_get_contents("http://ipinfo.io/{$ip}/json");
$details = json_decode($json);
return $details;
}
However, since I do not need the full details, I see that the site does allow to just grab single fields. So I am considering using these 2:
1) ipinfo.io/{ip}/region
2) ipinfo.io/{ip}/country
like so:
function ip_details($ip) {
$ip_state = file_get_contents("http://ipinfo.io/{$ip}/region");
$ip_country = file_get_contents("http://ipinfo.io/{$ip}/country");
return $ip_state . $ip_country;
}
OR would I be better off going with:
function ip_details($ip) {
$json = file_get_contents("http://ipinfo.io/{$ip}/geo");
$details = json_decode($json);
return $details;
}
The last one has the "/geo" in the url to slim down the selection from the first one with "/json". Currently I am leaning to the second option above by using 2 file_get_contents but wanted to know if it is slower than the last one having it in an array. Just want to minimize the load time. Or if any other method can be given it would be much appreciated.
In short, go for your second option, with a single request (file_get_contents makes a get request when parsed a url):
The result is a simple array, access the details you want via its key:
function ip_details($ip) {
$json = file_get_contents("http://ipinfo.io/{$ip}/geo");
$details = json_decode($json);
return $details;
}
$ipinfo = ip_details('86.178.xxx.xxx');
echo $ipinfo['country']; //GB
//etc
Regarding speed difference - 99% of the overhead is network latency, so making ONE request and parsing the details you need will be much faster than making 2 separate requests for individual details
$likes = $facebook->api("/me/likes");
foreach($likes['data'] as $page_likes) {
if($page_likes['id'] == "someid") {
}
}
Is there any simple way to find it instead of looping those hundreds, thousands likes?
Best method (to answer questions like this): Read documentation …!
https://developers.facebook.com/docs/reference/api/user/#likes:
“You can check if a User likes a specific page by issuing an HTTP GET to /PROFILE_ID/likes/PAGE_ID. […] This will return, in the data array, an object with the following fields if the user is connected to the page: […] If the user is not connected to the page, the data array will be empty.”
array_map or array_walk might be more efficient, but it depends on what you want to do with the data...