Learning how to parse basic json in to php echo of table - php

I know this has been done to death.
but i am really strugling
I have put together a webservice that generates a json,
i can and understand this bit in
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "http://marcom.domain.com/corp/pub.php");
curl_setopt($ch, CURLOPT_HEADER, 0);
this will dump out on the page [{"Torders":"3222","name":"john"},{"Torders":"579","name":"Kevin"}]
their is 5 in total but for this i am keeping it simple
I don't understand how to get these as an array so that my end result is a list
of name and Torders
the rendered html would be something like this
<li>john 3222</li>
<li>Kevin 579 </li>
please don't send me to php manual page for json decode cause i am strugling to understand this.
thank you

<?php
$json = file_get_contents('http://marcom.domain.com/corp/pub.php');
$people = json_decode($json);
?>
<ul>
<?php foreach ($people as $person): ?>
<li><?=$person->name?> <?=$person->Torders?></li>
<?php endforeach; ?>
</ul>
If you want to use curl, you'll want to set curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); and get the return from curl_exec()

U need to use json_decode()
$j = '[{"Torders":"3222","name":"john"},{"Torders":"579","name":"Kevin"}]';
$data = json_decode($j,true);
//print_r($data);
echo '<ul>';
foreach($data as $key=>$val){
echo '<li>'.$val['name'].' '.$val['Torders'].'</li>';
}
echo '</ul>';

Related

array becomes null because I can't send product id with get_file_content

I cannot see the details of the product I have selected in my product list with the woocommerce rest api
The main problem is that when I write the id of the product, I see it as json, but I have a problem when I want to include it in an array.
The main problem is that I can't send product id to single_product_connect.php with get_file_content, so it shows $ data array empty
form code;
<form action="single_product.php" name="update" method="get">
<td><input type="submit" name="edit"id="edit" value="<?= $row['id']; ?>"/></td></form>
single_product.php code;
<?php
$data = file_get_contents('http://localhost/api-woocommerce/single_product_connect.php');
$data = json_decode($data, true);
?>
<?php foreach ( $data as $row ) : ?>
<?= $row['id']; ?>
<?= $row['name']; ?> //I wrote a small piece for testing
<?php endforeach; ?>
single_product_connect.php code;
<?php $product_id = $_GET['edit'];?>
<?php echo json_encode($woocommerce->get("products/{$product_id}",$data)); ?>
error screen;
Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\api-woocommerce\single_product.php on line 19////The code in line 19:
<?php foreach ( $data as $row ) : ?>
When you use file_get_contents to get single_product_connect.php with http you can pass "edit" as a parameter if you concatenate query parameters to your url.
Try this change:
$id = /*some id*/;
$data = file_get_contents('http://localhost/api-woocommerce/single_product_connect.php?edit='.$id);
As you've mentioned can't send product id to single_product_connect.php with get_file_content so, when you're calling the remote url, the return value is an empty string which on json_decode() becomes null. You can check this by just adding this json_last_error() after json_decode() like this
$data = json_decode($data, true);
$erorr = json_last_error();
var_dump($data);
echo $error;
You can first append the product_id to the url and then can make the call to the url using file_get_contents like this
$url = "http://localhost/api-woocommerce/single_product_connect.php?product_id=<product_id>";
$data = json_decode(file_get_contents($url), true);
but I would suggest you to either use curl (recommended) or fsockopen.
With curl, it's very easy
// create curl resource
$ch = curl_init();
// set url
$url = "http://localhost/api-woocommerce/single_product_connect.php?product_id=<product_id>";
curl_setopt($ch, CURLOPT_URL, $url);
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
$data = json_decode($output, true);
if (json_last_error() !== JSON_ERROR_NONE) {
echo json_last_error_msg();
exit();
}
foreach ($data as $row) {
// do something
}

PHP - How to share JSON data between files

So I'm trying to make a simple API, I have tried lots of different things. I want to show a random number on my JSON object and a token to go with it, then store both in a database. I don't want this to happen when you visit the webpage I want the data to get sent to a DB and generated from a separate page.
The first step in this is getting data from a different file.
Here's what I tried first:
index.php:
<?php
$odds = rand(1, 100);
?>
<pre style="word-wrap: break-word; white-space: pre-wrap;">
{
"odds": <?php echo $odds;?>
}
</pre>
Here's the file I'm trying to get the data from:
<?php
$url = "https://flugscoding.com/random/";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, "Riverside API");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if(!$response = curl_exec($ch)) {
echo curl_error($ch);
}
curl_close($ch);
$data = json_decode($response, true);
echo $data->odds;
?>
Error:
Notice: Trying to get property 'odds' of non-object in D:\xxamp\htdocs\random\perp.php on line 16
What I tried after:
index.php:
<?php
$values = array("odds"=>rand(1, 100));
echo json_encode($values);
?>
Here's the file I'm trying to get the data from:
<?php
$json = file_get_contents("index.php");
echo $json;
// echo $json->odds;
?>
Error:
It doesn't show any data or errors, just a blank screen.
Does anyone have any solutions to this problem? I'm trying to make a provably fair system for a friend.
You're really close in both your examples:
#1
$data = json_decode($response, true);
echo $data->odds;
You're passing true into json_decode which makes it an associative array, not an object. So you will need to get the odds with $data['odds']; instead.
#2
$json = file_get_contents("index.php");
echo $json;
file_get_contents can either fetch a local file or remote file. In this case, you're passing a local file, so $json is the contents of the PHP code.
You can either:
(a) redesign it so that index.php is a function, and you can call the function from different files
(b) call index.php remotely and parse the results
a. Create a function in index.php that can get the odds:
<?php
function getData() [
return array("odds"=>rand(1, 100));
}
Then, in another file, you can:
<?php
require_once 'index.php';
$data = getData(); //now you have access to $data['odds'];
b. Call index.php remotely, like this:
$json = file_get_contents("http://localhost/index.php");
print_r(json_decode($json, true));

How can you stream results from an API in PHP

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?

Mulitple Instagram feeds on one page

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.

Parsing XML with PHP?

This has been driving me insane for about the last hour. I'm trying to parse a bit of XML out of Last.fm's API, I've used about 35 different permutations of the code below, all of which have failed. I'm really bad at XML parsing, lol. Can anyone help me parse the first toptags>tag>name 'name' from this XML API in PHP? :(
http://ws.audioscrobbler.com/2.0/?method=track.getinfo&api_key=b25b959554ed76058ac220b7b2e0a026&artist=Owl+city&track=fireflies
Which in that case ^ would be 'electronic'
Right now, all I have is this
<?
$xmlstr = file_get_contents("http://ws.audioscrobbler.com/2.0/?method=track.getinfo&api_key=b25b959554ed76058ac220b7b2e0a026&artist=Owl+city&track=fireflies");
$genre = new SimpleXMLElement($xmlstr);
echo $genre->lfm->track->toptags->tag->name;
?>
Which returns with, blank. No errors either, which is what's incredibly annoying!
Thank You very Much :) :) :)
Any help greatly, and by greatly I mean really, really greatly appreciated! :)
The <tag> tag is an array, so you should loop through them with a foreach or similar construct. In your case, just grabbing the first would look like this:
<?
$xmlstr = file_get_contents("http://ws.audioscrobbler.com/2.0/?method=track.getinfo&api_key=b25b959554ed76058ac220b7b2e0a026&artist=Owl+city&track=fireflies");
$genre = new SimpleXMLElement($xmlstr);
echo $genre->track->toptags->tag[0]->name;
Also note that the <lfm> tag is not needed.
UPDATE
I find it's much easier to grab exactly what I'm looking for in a SimpleXMLElement by using print_r(). It'll show you what's an array, what's a simple string, what's another SimpleXMLElement, etc.
Try using
$url = "http://ws.audioscrobbler.com/2.0/?method=track.getinfo&api_key=b25b959554ed76058ac220b7b2e0a026&artist=Owl+city&track=fireflies";
$xml = simplexml_load_file($url);
echo $xml->track->toptags->tag[0]->name;
Suggestion: insert a statement to echo $xmlstr, and make sure you are getting something back from the API.
You don't need to reference lfm. Actually, $genre already is lfm. Try this:
echo $genre->track->toptags->tag->name;
if you wan't to read xml data please follow those steps,
$xmlURL = "your xml url / file name goes here";
try {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $xmlURL);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-type: text/xml'
));
$content = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
$obj = new SimpleXMLElement($content);
echo "<pre>";
var_dump($obj);
echo "</pre>";
}
catch(Exception $e){
var_dump($e);exit;
}
You will get array formate of whole xml file.
Thanks.

Categories