I have successfully put an Instagram feed for a specific user on my website, but having very little experience with PHP I cannot figure out how to simply repeat the process. I'm looking to showcase two different users, side by side in one div.
<?php
// http://jelled.com/instagram/lookup-user-id/
$userid = "userid";
// http://instagram.com/developer/
$clientid = "clientid";
// http://jelled.com/instagram/access-token/
$accessToken = "token";
// number of photos to return
$count = "4";
// Gets our data
function fetchData($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
// Pulls and parses data.
$result = fetchData("https://api.instagram.com/v1/users/{$userid}/media/recent/?access_token={$accessToken}&count={$count}");
$result = json_decode($result);
// cycles through the json tree and uses the low res url in the img tag
echo "<ul>";
foreach ($result->data as $photo) {
$img = $photo->images->{$display_size="thumbnail"};
echo "<li><a href='{$photo->link}'><img src='{$img->url}' /></a></li>";
}
echo "</ul>";
?>
If I just paste the code in again, the whole page stops working. I'm guessing this is something simple, but I don't know exactly what I'm looking for! Should this code be in a separate file that is linked into my website- rather than throwing some PHP inside an HTML Bootstrap site?
Thanks in advance.
EDIT
I was able to get this working by using the answer below. I wanted each account to have it's own div, and the only way I know how to do that is in the html file- which would mean I still need to link to two different files. I created one file with the correct code, and another with this:
<?php
// Set User ID here for different profile
//$userid = "idHere";
$userid = "296517730";
$result = fetchData("https://api.instagram.com/v1/users/{$userid}/media/recent/?client_id={$clientid}&count={$count}");
$result = json_decode($result);
// cycles through the json tree and uses the low res url in the img tag
echo "<ul>";
foreach ($result->data as $photo) {
$img = $photo->images->{$display_size="thumbnail"};
echo "<li><a href='{$photo->link}'><img src='{$img->url}' /></a></li>";
}
echo "</ul>";
?>
It was working just fine on my domain, but when I moved it to my client's domain I'm getting this error: Warning: Invalid argument supplied for foreach() in /home/savenors/savenorsmarket.com/bostoninsta.php on line 53
What happened? I'm guessing whatever I did to get this to work wasn't really working.. but it looked fine to me. Any ideas? This is the website: http://www.savenorsmarket.com
Here's code that is working on my machine pulling in twice. It pulls the same user pictures twice, but to fix this just reset the user id variable before making a second call to fetchData();
<?php
$userid = "idHere";
// http://instagram.com/developer/
$clientid = "IDhere";
// number of photos to return
$count = "4";
// Gets our data
function fetchData($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
// Pulls and parses data.
$result = fetchData("https://api.instagram.com/v1/users/{$userid}/media/recent/?client_id={$clientid}&count={$count}");
$result = json_decode($result);
// cycles through the json tree and uses the low res url in the img tag
echo "<ul>";
foreach ($result->data as $photo) {
$img = $photo->images->{$display_size="thumbnail"};
echo "<li><a href='{$photo->link}'><img src='{$img->url}' /></a></li>";
}
echo "</ul>";
// Set User ID here for different profile
//$userid = "idHere";
$result = fetchData("https://api.instagram.com/v1/users/{$userid}/media/recent/?client_id={$clientid}&count={$count}");
$result = json_decode($result);
// cycles through the json tree and uses the low res url in the img tag
echo "<ul>";
foreach ($result->data as $photo) {
$img = $photo->images->{$display_size="thumbnail"};
echo "<li><a href='{$photo->link}'><img src='{$img->url}' /></a></li>";
}
echo "</ul>";
?>
Also note that I'm using the client_id over the access_token. It should work either way though.
Related
is there a way in PHP, perhaps with an external library, to stream results from an API that responds with JSON data?
For instance I have the following code to get the data:
$resultsAPI = "https://www.example.com/api/results.json?
app_id=$app_id&token=$token&page=1&limit=10";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $resultsAPI);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json;api_version=2' ));
$resp = curl_exec($curl);
curl_close($curl);
$results = json_decode($resp, true)['results'];
foreach ($results as $key=>$resultImage) {
$resultImage= "$resultImage[images]?app_id=$app_id&token=$token";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $resultImage);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$resp = curl_exec($curl);
curl_close($curl);
$image = json_decode($resp, true);
$results[$key]['image1'] = $image['image1'];
}
echo '<div class="card"><ul>';
foreach ($results as $result) {
echo '<li>';
echo '<span><p>'.$result['title'].'</p></span>';
echo '<span><p>'.$result['description'].'</p></span>';
echo '<span><img src="'.$result['image1'].'"></span>';
echo '</li>';
}
echo '</ul></div>';
It can take some time to load all data because it is going to loop over some large files. Is it possible to start streaming the results when it has the first data?
In the image below it shows what I am trying to explain. The data is being loaded in to the skeleton one by one:
Any thoughts on this would be very helpful and or if it is possible at all.
I think you're run into the wrong direction.
HTML begin to render after load all the html. So fetch the html with stream is not work for you.
In the demo, it just load a simple html page. Then load the other parts of the page with something like ajax. Each time a part loaded then render it.
Why not merge the the foreach loops? I haven't tested this but items should be echoed very iteration.
echo '<div class="card"><ul>';
foreach ($results as $key=>$result) {
$resultImage= "$result[images]?app_id=$app_id&token=$token";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $resultImage);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$resp = curl_exec($curl);
curl_close($curl);
$image = json_decode($resp, true);
$results[$key]['image1'] = $image['image1'];
echo '<li>';
echo '<span><p>'.$result['title'].'</p></span>';
echo '<span><p>'.$result['description'].'</p></span>';
if(isset($image['image1'])){
echo '<span><img src="'.$result['image1'].'"></span>';
}
echo '</li>';
}
echo '</ul></div>';
I hope that helps
As Kris Roofe said you may need ajax or axios call to output your data with some effects and animations exactly like the image that you attached in your question, your application need to be rendered first with all of it's HTML tags and assets like CSS and Javascript files then you can output some data and show it with animations by using ajax or axios and ofcurse you have more control over your data streaming in this case by using ajax or axios in client-side but you can also do it in your server-side but typically I prefer to do these things in client-side.
by the way if you insist to doing this in this way you can use flush() and ob_flush() to immediately output your data before the while loop ends.
Someone has already mentioned this in php official documentation link. You can check and read full documentation about output buffering and these methods.
You should merge your two foreach loops together and then add these two methods add the end of your loop so it will make it to output your data immediately after each loop iterate.
foreach($results as $key=>$resultImage){
//fetch images data such as title, description, and image itself in this loop
// and aslo echo your html tags in here.
// echo '<li>';
// echo '<span><p>'.$result['title'].'</p></span>';
// echo '<span><p>'.$result['description'].'</p></span>';
// echo '<span><img src="'.$result['image1'].'"></span>';
// echo '</li>';
}
I wrote some comments in your for loop to show you that you should merge your loops together, because you are trying to initialize $results variable in your first loop, and then after finishing that loop you are iterating in $results variable to show output data. so you can't output data immediately with two loops in here because your second loop depends on first one and it will not start iterating until the first one finishes. check this little code that I wrote to demonstrate the usage of these two methods:
$curl = curl_init();
for($i=0;$i<5;$i++){
curl_setopt($curl, CURLOPT_URL, 'example.com');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($curl);
$output = json_decode($output);
foreach($output as $key=>$value){
echo 'key: '.$key;
echo '$value: '.$value;
ob_flush();
flush();
}
}
I would highly recommend you to read about output buffering to implement it correctly in your projects.
I hope this could help you.
HTML starts rendering when some of it arrives. It does not have to be complete source. In PHP you can "send what you already echoed" via ob_flush() and flush() calls. This way it will immediately display in the browser. This can be paired with JSON stream parsing using for example halaxa/json-machine, so the result can look something like this:
<?php
echo '<div class="card"><ul>';
foreach (JsonMachine::fromStream($jsonStreamResource) as $result) {
echo '<li>';
echo '<span><p>'.$result['title'].'</p></span>';
echo '<span><p>'.$result['description'].'</p></span>';
echo '<span><img src="'.$result['image1'].'"></span>';
echo '</li>';
ob_flush();
flush();
}
echo '</ul></div>';
Fetch limited records while rendering html first load. Once page load fully then call a ajax function which will fetch next page rows. Definitely it is the tested method.
<script>
var items = [{item1}, {item2}];
$(document).ready(function() {
$.each(items, function(index, item) {
$('.card').append('<li>'+ '<span><p>'+item['title']+'</p></span>' +
'</li>');
});
});`enter code here`
</script>
OR
You may call ajax function for first page records after html rendered fully.
How do I load a JSON object from a file with ajax?
I am trying to get information from a XML Rest API.
I can get everything but not the images.
I can display all info, but when it comes on images I get 401 error
Failed to load resource: the server responded with a status of 401 ().
My username and password are correct. The only way to get the images display is if I login to this API in a different window. Then all images are displayed.
Am I doing something wrong ? Here is my php code:
function CallAPI($url){
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "usr:psw");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
curl_close($curl);
return $result;
}
$a = "query SQL";
$asd = $database->query($a);
while($row = sqlsrv_fetch_array($asd)){
echo $url = $row['url']; // I can get this data display
$row['hotel_name'];
$a = CallAPI($url);
$axml = new SimpleXMLElement($a);
$img_link = $axml->item->images;
foreach ($img_link->image as $value) {
echo "<img src='".$value->sizes->size[1]->attributes('http://www.w3.org/1999/xlink')."' class='img-responsive' />";
}
So your problem must be that this link need authentication as well. So try make the call for $value->sizes->size[1]->attributes('http://www.w3.org/1999/xlink') to pass user and pass.
So you code should look like this
while($row = sqlsrv_fetch_array($asd)){
$url = $row['url'];
$row['hotel_name']; // No use of this one, maybe you use it on your end
$a = CallAPI($url);
$axml = new SimpleXMLElement($a);
$img_link = $axml->item->images;
foreach ($img_link->image as $value) {
/*I am adding the link to a variable*/
$imgLinkFromValue = $value->sizes->size[1]->attributes('http://www.w3.org/1999/xlink');
$img = CallAPI($imgLinkFromValue );
/* Now if you still get a link just pass the variable */
echo "<img src='$img->**link or href or anything you get**' class='img-responsive' />";
}
UPDATE
If you getting text or symbols maybe you have to use base64_encode().
Try this :
$img = base64_encode(CallAPI($imgLinkFromValue ));
echo '<img src="data:image/jpeg;base64,' . $img . '" class="img-responsive" />'
You can always change the data inside src to png or gif, depends on what you need.
For more Info about base64_encode function you can use this link.
http://php.net/manual/en/function.base64-encode.php
Bear with my inexperience here, but can anyone point me in the right direction for how I can change the PHP script below to output each variable that is parsed from the XML file (title, link, description, etc) as a POST method instead of just to an HTML page?
<?php
$html = "";
$url = "http://api.brightcove.com/services/library?command=search_videos&any=tag:SMGV&output=mrss&media_delivery=http&sort_by=CREATION_DATE:DESC&token= // this is where the API token goes";
$xml = simplexml_load_file($url);
$namespaces = $xml->getNamespaces(true); // get namespaces
for($i = 0; $i < 80; $i++){
$title = $xml->channel->item[$i]->video;
$link = $xml->channel->item[$i]->link;
$title = $xml->channel->item[$i]->title;
$pubDate = $xml->channel->item[$i]->pubDate;
$description = $xml->channel->item[$i]->description;
$titleid = $xml->channel->item[$i]->children($namespaces['bc'])->titleid;
$html .= "<h3>$title</h3>$description<p>$pubDate<p>$link<p>Video ID: $titleid<p>
<iframe width='480' height='270' src='http://link.brightcove.com/services/player/bcpid3742068445001?bckey=AQ~~,AAAABvaL8JE~,ufBHq_I6FnyLyOQ_A4z2-khuauywyA6P&bctid=$titleid&autoStart=false' frameborder='0'></iframe><hr/>";/* this embed code is from the youtube iframe embed code format but is actually using the embedded Ooyala player embedded on the Campus Insiders page. I replaced any specific guid (aka video ID) numbers with the "$guid" variable while keeping the Campus Insider Ooyala publisher ID, "eb3......fad" */
}
echo $html;
?>
#V.Radev Here's another PHP script using cURL that I think will work with the API I'm trying to send data to:
<?PHP
$url = 'http://api.brightcove.com/services/post';
//open connection
$ch = curl_init($url);
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, '$title,$descripton,$url' . stripslashes($_POST['$title,$description,$url']));
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
// Enable for Charles debugging
//curl_setopt($ch,CURLOPT_PROXY, '127.0.0.1:8888');
$result = curl_exec($ch);
curl_close($ch);
print $result;
?>
My question is, how can I pass the variables from my feed parsing script (title, description, URL) to this new script?
I have this code from Brightcove, can I just output the variables from my parser script and send to this PHP script so that the data goes to the API?
<?php
// This code example uses the PHP Media API wrapper
// For the PHP Media API wrapper, visit http://docs.brightcove.com/en/video-cloud/open-source/index.html
// Include the BCMAPI Wrapper
require('bc-mapi.php');
// Instantiate the class, passing it our Brightcove API tokens (read, then write)
$bc = new BCMAPI(
'[[READ_TOKEN]]',
'[[WRITE_TOKEN]]'
);
// Create an array of meta data from our form fields
$metaData = array(
'name' => $_POST['bcVideoName'],
'shortDescription' => $_POST['bcShortDescription']
);
// Move the file out of 'tmp', or rename
rename($_FILES['videoFile']['tmp_name'], '/tmp/' . $_FILES['videoFile']['name']);
$file = '/tmp/' . $_FILES['videoFile']['name'];
// Create a try/catch
try {
// Upload the video and save the video ID
$id = $bc->createMedia('video', $file, $metaData);
echo 'New video id: ';
echo $id;
} catch(Exception $error) {
// Handle our error
echo $error;
die();
}
?>
Post is a request method to access a specific page or resource. With echo you are sending data which means that you are responding. In this page you can only add response headers and access it with a request method such as post, get, put etc.
Edit for API request as mentiond in the comments:
$curl = curl_init('your api url');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $your_data_to_send);
$result_from_api = curl_exec($curl);
curl_close($curl);
(I'm scraping this stuff with the permission of the website in question, by the way).
Pretty simple web scraper, was working fine when I was loading all the links by hand, but when I've tried to load them in via JSON and variables (so I can do lots of scraping with the one script and make the process more modular by just adding more links to JSON) it runs on an infinite loop.
(Page has been loading for about 15 minutes now)
Here is my JSON. Only one store is in there for testing purposes but there is going to be about 15 more.
[
{
"store":"Incu Men",
"cat":"Accessories",
"general_cat":"Accessories",
"spec_cat":"accessories",
"url":"http://www.incuclothing.com/shop-men/accessories/",
"baseurl":"http://www.incuclothing.com",
"next_select":"a.next",
"prod_name_select":".infobox .fn",
"label_name_select":".infobox .brand",
"desc_select":".infobox .description",
"price_select":"#price",
"mainImg_select":"",
"more_imgs":".product-images",
"product_url":".hproduct .photo-link"
}
]
Here is the PHP scraper code:
<?php
//Set infinite time limit
set_time_limit (0);
// Include simple html dom
include('simple_html_dom.php');
// Defining the basic cURL function
function curl($url) {
$ch = curl_init();
// Initialising cURL
curl_setopt($ch, CURLOPT_URL, $url);
// Setting cURL's URL option with the $url variable passed into the function
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
// Setting cURL's option to return the webpage data
$data = curl_exec($ch);
// Executing the cURL request and assigning the returned data to the $data variable
curl_close($ch);
// Closing cURL
return $data;
// Returning the data from the function
}
function getLinks($catURL, $prodURL, $baseURL, $next_select) {
$urls = array();
while($catURL) {
echo "Indexing: $url" . PHP_EOL;
$html = str_get_html(curl($catURL));
foreach ($html->find($prodURL) as $el) {
$urls[] = $baseURL . $el->href;
}
$next = $html->find($next_select, 0);
$url = $next ? $baseURL . $next->href : null;
echo "Results: $next" . PHP_EOL;
}
return $urls;
}
$string = file_get_contents("jsonWorkers/incuMens.json");
$json_array = json_decode($string,true);
foreach ($json_array as $value){
$baseURL = $value['baseurl'];
$catURL = $value['url'];
$store = $value['store'];
$general_cat = $value['general_cat'];
$spec_cat = $value['spec_cat'];
$next_select = $value['next_select'];
$prod_name = $value['prod_name_select'];
$label_name = $value['label_name_select'];
$description = $value['desc_select'];
$price = $value['price_select'];
$prodURL = $value['product_url'];
if (!is_null($value['mainImg_select'])){
$mainImg = $value['mainImg_select'];
}
$more_imgs = $value['more_imgs'];
$allLinks = getLinks($catURL, $prodURL, $baseURL, $next_select);
}
?>
Any ideas why the script would be running infinitely and not returning anything/stopping/printing anything to screen? I'm just gonna let it run until it stops. When I was doing this by hand it would only take a minute or so, sometimes less, so I'm sure it's a problem with my variables/json but I can't for the life of me see what the issues lie.
Can anyone take a quick look and point me in the right direction?
There is a problem with your while($catURL) loop. What do you want to do ?
Moreover, you can force to display information on your browser with the flush() command.
I wanted to ask you help I have an xml source (http://livefmhits.6te.net/nowplay.xml) it gives me the source of the song and I wanted to remove the cover through the lastfm (artist.getinfo) in echo I tried as follows:
<?php
$xml = simplexml_load_file('http://livefmhits.6te.net/nowplay.xml');
$artist = urlencode($xml->TRACK["ARTIST"]);
$url = 'http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist='.$artist.&api_key=b25b959554ed76058ac220b7b2e0a026;
$xml2 = #simplexml_load_file($url);
if ($xml2 === false)
{
echo("Url failed"); // do whatever you want to do
}
else
{
if($xml2->track->album->image[3])
{
echo '<img src="';
echo((string) $xml2->track->album->image[3]);
echo '">';
}
else
{
echo "<img src='http://3.bp.blogspot.com/-SEsYAbASI68/VZ7xNuKy-GI/AAAAAAAAA3M/IWcGRDoXXms/s1600/capaindisponivel.png'"; // do whatever you want to do
}
}
I'm not able to extract the source must be wrong echo, I like to remove the image that says "mega". I present to you the complete link
http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&lang=ru&artist=COLDPLAY&api_key=ae9dc375e16f12528b329b25a3cca3ee and yet I was to do a post yours but I could not (Get large artist image from last.fm xml (api artist.getinfo))
I came to ask your help in this work from the outset thanks for availability
Here is how I'm doing it in json. It's pretty much the same in XML.
First, we define the API KEY:
define('YOUR_API_KEY', 'b25b959554ed76058ac220b7b2e0a026');
It's better to separate it from the code, it makes things easier if you need to reuse it somewhere else in your code. (for eg. in another function)
Then, we create the 2 functions we need to make the magic happen.
1) To query Lastfm's API and get its content, we will use CURL:
function _curl($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
if(strtolower(parse_url($url, PHP_URL_SCHEME)) == 'https')
{
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,1);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,1);
}
curl_setopt($ch, CURLOPT_URL, $url);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
2) Lastfm offers many options. Personally, I find it's easier to separate main queries into functions. But as you simply target images, here is the function I'd use:
function lfm_img($artist)
{
$url = "http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=$artist&api_key=".YOUR_API_KEY."&format=json";
$json = _cul($url);
$data = str_ireplace("#text", "text", $json);
$list = json_decode($data);
//If an error occurs...
if($list->error)
return 'ERROR.'. $list->error;
//That's where we get the photo. We try to get the biggest size first, if not we try smaller sizes. Returns '0' if nothing is found.
if($list->artist->image[4])
$img = $list->artist->image[4]->text;
else if($list->artist->image[3])
$img = $list->artist->image[3];
else if($list->artist->image[2])
$img = $list->artist->image[2];
else if($list->artist->image[1])
$img = $list->artist->image[1];
else if($list->artist->image[0])
$img = $list->artist->image[0];
else
$img = 0;
return $img;
}
And finally, use them:
$artist_query = 'Nirvana';
$artist_image = lfm_img($artist);
//display image
echo '<img src="'. $artist_image .'" alt="'. $artist_query .'" />';
I think it's self explanatory here. ;)
Hope it helped!