How to iterate over an item of objects and array - php

I do not know how to iterate on this output, it can be simple but try several methods without success.
I have the result of a query that throws a json with objects and fixes, but I can not get the cpu, memory and disk values:
<?php
// How to read influx data with curl
$query = urlencode("select * from calls limit 1");
$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, 1); //timeout in seconds
curl_setopt($ch, CURLOPT_URL,"http://127.0.0.1:8086/query?db=myDB&q=$query");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$res = json_decode(curl_exec ($ch));
curl_close ($ch);
var_dump($res);
?>
and I get this output:
{"results":[{"statement_id":0,"series":[{"name":"custom","tags":{"hostname":"LINUX01"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",1,78,0,0]]},{"name":"custom","tags":{"hostname":"LINUX02"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",6,48,0,0]]},{"name":"custom","tags":{"hostname":"LINUX03"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",5,47,0,0]]},{"name":"custom","tags":{"hostname":"LINUX04"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",35,94,0,0]]},{"name":"custom","tags":{"hostname":"LINUX05"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",3,47,0,0]]},{"name":"custom","tags":{"hostname":"LINUX06"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",57,25,0,0]]},{"name":"custom","tags":{"hostname":"LINUX07"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",40,47,0,0]]},{"name":"custom","tags":{"hostname":"LINUX08"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",41,30,0,0]]},{"name":"custom","tags":{"hostname":"ues90078"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",40,20,0,0]]},{"name":"custom","tags":{"hostname":"LINUX09"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",33,45,0,0]]},{"name":"custom","tags":{"hostname":"LINUX041"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",31,30,0,0]]},{"name":"custom","tags":{"hostname":"LINUX042"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",33,8,0,0]]},{"name":"custom","tags":{"hostname":"LINUX043"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",54,10,0,0]]}]}]}
Try for example:
foreach ($res as $test) {
echo $test->statement_id->cpu;
}
I wish I could get this:
hostname time cpu mem load load
linux01 1970-01-01T00:00:00Z 1 78 0 0
Sorry for my bad English.

You will have a difficult time working with this data as is, because most of the data is unkeyed, and that makes it misleading to work with as an object. It would be easier in this case if you worked with the array. You can do this by using true as the second parameter of the decode.
$data = json_decode(curl_exec ($ch), true);
$results = $data['results'];
foreach ($results['series'] as $server) {
$cpuIndex = array_search('cpu', $server['columns']);
echo $server['values'][$cpuIndex];
}

You need to convert it to from JSON to an Object or Array.
Here's a common Array situation:
$results = json_decode('{"results":[{"statement_id":0,"series":[{"name":"custom","tags":{"hostname":"LINUX01"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",1,78,0,0]]},{"name":"custom","tags":{"hostname":"LINUX02"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",6,48,0,0]]},{"name":"custom","tags":{"hostname":"LINUX03"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",5,47,0,0]]},{"name":"custom","tags":{"hostname":"LINUX04"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",35,94,0,0]]},{"name":"custom","tags":{"hostname":"LINUX05"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",3,47,0,0]]},{"name":"custom","tags":{"hostname":"LINUX06"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",57,25,0,0]]},{"name":"custom","tags":{"hostname":"LINUX07"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",40,47,0,0]]},{"name":"custom","tags":{"hostname":"LINUX08"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",41,30,0,0]]},{"name":"custom","tags":{"hostname":"ues90078"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",40,20,0,0]]},{"name":"custom","tags":{"hostname":"LINUX09"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",33,45,0,0]]},{"name":"custom","tags":{"hostname":"LINUX041"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",31,30,0,0]]},{"name":"custom","tags":{"hostname":"LINUX042"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",33,8,0,0]]},{"name":"custom","tags":{"hostname":"LINUX043"},"columns":["time","cpu","mem","load","load"],"values":[["1970-01-01T00:00:00Z",54,10,0,0]]}]}]}', true);
foreach ($results["results"][0]["series"] as $array) {
echo "<table>";
echo "<thead>";
echo "<tr>";
foreach ($array["columns"] as $value) {
echo "<th>{$value}</th>";
}
echo "</tr>";
echo "</thead>";
echo "<tbody>";
echo "<tr>";
foreach ($array["values"][0] as $value) {
echo "<td>{$value}</td>";
}
echo "</tr>";
echo "</tbody>";
echo "<table>";
}
If you want something specific:
foreach ($results["results"][0]["series"] as $array) {
foreach ($array["columns"] as $key => $value) {
if ($value === "cpu") $column = $key;
}
echo "cpu: {$array["values"][0][$column]}.<br>";
}
To add hostname, simple add:
echo "<tr>";
echo "<th colspan=" . count($array["columns"]) . ">{$array["tags"]["hostname"]}</th>";
echo "</tr>";
after echo "<thead>";.

Related

Why is my PHP foreach loop not correctly outputting data into HTML Table?

I am outputting data from a text file (not csv) into an html table using php. I am exploding the data and it returns as an array but when I use a foreach loop the data turns back into a string so I am unable to sort(). Also, the data is printing into the table 5 times as a duplicate for each book and author. How do I keep my array as an array in the foreach loop so it can be sorted and how do I only get each line to display one time in the html table? (to be properly looped through to get the display I am looking for?).
PHP
<?php
$filename = 'books.txt';
list($rows, $html_table ) = returnTable($filename);
if (empty($rows))
{
print "<p>Total Rows in Table: ".$rows."</p>";
print $html_table;
}
else
{
print "No file found";
}
//Read Information from a File into an HTML table
function returnTable($filename)
{
$arr = array();
$html_table = "<table border='2'>";
$html_table.= "<tr>";
$html_table.= "<th>Title</th>";
$html_table.= "<th>Author</th>";
$html_table.= "</tr>\n";
$line_ctr = 0;
$fp = fopen($filename, 'r');
if ($fp)
{
while(true)
{
$line = fgets($fp);
if (feof($fp))
{
break;
}
$line_ctr++;
$arr = list($title, $author) = explode('*', $line);
//var_dump($arr); // returns an array but changes to a string in the loop below!
foreach($arr as $books){
$html_table.= "<tr>";
$html_table.= "<td>".$title."</td>";
$html_table.= "<td>".$author."</td>";
$html_table.= "</tr>\n";
}//END OF FOREACH LOOP
} //END OF WHILE LOOP
$html_table.= "</table>";
fclose($fp ); //Close file
//AT THIS POINT html_table is a string again but why?
$return_data = array($line_ctr, $html_table);
} else {
$return_data = array("error", "No Content here");
}
return $return_data;
}
?>
From the comments in your code it looks like you are confusing the $arr and $html_table as the same variable. $arr is always an array. $html_table is always a string.
You are getting duplicates because the foreach loop is within the while loop.
It looks like you need to take the foreach loop out of the while loop. After the while loop is complete do the sorting that you want on $arr and then run the foreach loop to create your html table.
I would try something like the following:
Change $arr = list($title, $author) = explode('*', $line); to $books[] = list($title, $author) = explode('*', $line);
This will make $books a multidimensional array like the following:
Array (
[0] => Array
(
[0] => The Shining
[1] => Stephen King
)
[1] => Array
(
[0] => Interview With The Vampire
[1] => Anne Rice
)
)
With the foreach loop moved outside of the while loop, update the foreach loop like this:
foreach($books as $book) {
$html_table .= "<td>" . $book[0] . "</td>";
$html_table .= "<td>" . $book[1] . "</td>";
}
I'm not sure what type of sorting you will need to do so you may need to create your books array differently than this example.
Try to output 3 variables from your function.
Seperate it into 3 parts, table header, looping contents and table footer.
The function output something like
list($table_header, $rows, $table_footer ) = returnTable($filename);
In your function make the $arr data only output as $rows.
Then the final html output something like
echo $table_header.$rows.$table_footer
Your code in this state contains many minor error which prevent you to get the expected result .I put the explanations in the comments so pay attention to them in order to avoid such errors in the future:
$filename = 'books.txt';
list($rows, $html_table ) = returnTable($filename);
if ($rows>0)//here i change something look out
{
print "<p>Total Rows in Table: ".$rows."</p>";
print $html_table;
}
else
{
print "No file found";
}
//Read Information from a File into an HTML table
function returnTable($filename)
{
// $arr = array();you don't need at all this
$html_table = "<table border='2'>";
$html_table.= "<tr>";
$html_table.= "<th>Title</th>";
$html_table.= "<th>Author</th>";
$html_table.= "</tr>\n";
$line_ctr = 0;
$fp = fopen($filename, 'rb');
if ($fp)
{
while(true)
{
$line = fgets($fp);
$line_ctr++;
/*$arr = */list($title,$isbn, $author) = explode('*', $line);//i got a sample of the books.txt content from your previous question so i add isbn but you can remove it
// foreach($arr as $books){ no no and no
$html_table.= "<tr>";
$html_table.= "<td>".$title."</td>";
$html_table.= "<td>".$isbn."</td>";
$html_table.= "<td>".$author."</td>";
$html_table.= "</tr>\n";
// }//END OF FOREACH LOOP
if (feof($fp)) //will now allow the last element to be fetched too
{
break;
}
} //END OF WHILE LOOP
$html_table.= "</table>";
fclose($fp ); //Close file
$return_data = array($line_ctr, $html_table);
} else {
$return_data = array("error", "No Content here");
}
// return $rtn; no
return $return_data;
}
This code works perfectly .I know it because I test it with a sample of your previous related question
But Based on this comment:
This works and brings back the data into a table but brings the data
back as a string. I need to be able to sort the data as well. Can you
implement a sort() in this code?
Implement sort in a code which use fopen and fgets can be really complex and painful however the following code should satisfy your expectation:
function returnTable($filename,$sortby='title',$sortType=SORT_REGULAR,$sortOrder=SORT_ASC)
{
$column=[];
$line_ctr = 0;
$books= array_map(
function($val) use(&$column,$sortby,&$line_ctr){
$line_ctr++;
$val=array_combine(['title','isbn','author'],array_map('trim',str_getcsv($val,'*')));
$column[]=$val[strtolower($sortby)];
return $val;
},
file($filename,FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES));
if($books){
$sortOrder=$sortOrder!==SORT_ASC&&$sortOrder!==SORT_DESC?SORT_ASC:$sortOrder;
$sortType=in_array( $sortType,
[
SORT_REGULAR ,SORT_NUMERIC,SORT_STRING ,
SORT_LOCALE_STRING ,SORT_NATURAL,SORT_FLAG_CASE,
SORT_FLAG_CASE|SORT_STRING,SORT_FLAG_CASE|SORT_NATURAL
],
true
)?$sortType:SORT_REGULAR;
$html_table = "<table border='2'>";
$html_table.= "<tr>";
$html_table.= "<th>Title</th>";
$html_table.= "<th>ISBN</th>";
$html_table.= "<th>Author</th>";
$html_table.= "</tr>\n";
array_multisort($column,$sortOrder,$sortType,$books);
unset($column);
array_map(
function($book) use(&$html_table){
list($title,$isbn, $author) = array_values($book);
$html_table.= "<tr>";
$html_table.= "<td>".$title."</td>";
$html_table.= "<td>".$isbn."</td>";
$html_table.= "<td>".$author."</td>";
$html_table.= "</tr>\n";
}
,
$books
);
$html_table.= "</table>";
$return_data = array($line_ctr, $html_table);
} else {
$return_data = array("error", "No Content here");
}
return $return_data;
}
with this you should be able to sort by case insensitive column name in ascending or descending order using these types of sort SORT_REGULAR ,SORT_NUMERIC,SORT_STRING ,SORT_LOCALE_STRING,SORT_NATURAL,SORT_FLAG_CASE,SORT_FLAG_CASE|SORT_STRING,SORT_FLAG_CASE|SORT_NATURAL

Print each element of json curl execution

I have a curl function to call a service that return output like this
[{"idpacket":1,"packetname":"Silver","packetdesc":"Silver is da best","packetprize":"Rp 20000","packettime":"365 days"}]
I wanna echo all of element into table row
How i do that? I always get error on foreach function. Please help
This is my code:
<?php
//step1
$cSession = curl_init();
//step2
curl_setopt($cSession,CURLOPT_URL,"http://localhost:8080/packet");
curl_setopt($cSession,CURLOPT_RETURNTRANSFER,true);
curl_setopt($cSession,CURLOPT_HEADER, false);
//step3
$result=curl_exec($cSession);
//step4
curl_close($cSession);
//
foreach ((array) $result as $item) {
print_r($item['idpacket']);
}
?>
Thank you :)
I got this conclusion as I understood
write this code and check :
print_r((array)$result);
its place your JSON into an array does not decode your JSON like this:
Array
(
[0] => [{"idpacket":1,"packetname":"Silver","packetdesc":"Silver is da best","packetprize":"Rp 20000","packettime":"365 days"}]
)
if you want to access 'idpacket'
write like this:
$result_array = json_decode($result,true);
foreach ((array) $result_array as $item) {
print_r($item['idpacket']);
}
You could write something like
<?php
$resultArr = json_decode($result,true);
$header="<tr>";
$row="<tr>";
echo "<table>";
foreach($resultArr[0] as $col => $val)
{
$header.="<td>".$col."</td>";
$row.="<td>".$val."</td>";
}
$header.="</tr>";
$row.="</tr>";
echo $header;
echo $row;
echo "</table>";
?>

PHP sort multiple arrays

I have a PHP report which goes out to an array of servers to get their uptime. Then present the uptime in a table. Very simple.
I'm looking to see how to sort this array so that the highest uptime is at the top of the list.
I know about arsort() but I don't know how to apply it to this statement because of the foreach building the table dynamically.
Here's my code:
$servers = server1,server2,server3
foreach ($servers as $srv) {
$output = array(); // Reset the $output array each time
exec("/root/get_report_uptime.sh $srv",$output,$retval);
echo "<tr>";
echo "<td><a href='http://$srv/' target='_blank'>$srv</a></td>";
echo "<td>$output[0] days</td>";
echo "</tr>";
}
$output[0] returns a number like "100". Looking to sort by $output[0] while keeping the $srv linked to it.
$days = array()
foreach ($servers as $srv) {
$output = array(); // Reset the $output array each time
exec("/root/get_report_uptime.sh $srv",$output,$retval);
$days[$srv] = $output[0];
}
arsort($days);
foreach($days as $srv => $day) {
echo "<tr>";
echo "<td><a href='http://".$srv."/' target='_blank'>".$srv."</a></td>";
echo "<td>".$day." days</td>";
echo "</tr>";
}

cURL and json data convert into array and get only temp data

I am new using json data. I am trying to call an api using cURL and converting it into array. I just want the temp data using foreach loop. But i am getting Invalid argument supplied for foreach() error. My code
$cSession = curl_init();
curl_setopt($cSession,CURLOPT_URL,"http://api.openweathermap.org/data/2.5/forecast/daily?q=dhaka%2Cbangladesh&mode=json&units=metric&cnt=3");
curl_setopt($cSession,CURLOPT_RETURNTRANSFER,true);
curl_setopt($cSession,CURLOPT_HEADER, false);
$result = curl_exec($cSession);
curl_close($cSession);
//echo $result;
//$i = 3 as i am requesting 3 day data
for ($i=0; $i <3 ; $i++) {
foreach ($result as $value) {
echo $value['temp'][0]['day'];
echo $value['temp'][0]['min'];
echo $value['temp'][0]['max'];
echo $value['temp'][0]['night'];
echo $value['temp'][0]['eve'];
echo $value['temp'][0]['morn'];
}
}
This should work for you:
$json = json_decode($result);
$res = $json->{'list'};
foreach ($res as $value) {
echo $value->{'temp'}->{'day'} . "<br>";
echo $value->{'temp'}->{'min'} . "<br>";
echo $value->{'temp'}->{'max'} . "<br>";
echo $value->{'temp'}->{'night'} . "<br>";
echo $value->{'temp'}->{'eve'} . "<br>";
echo $value->{'temp'}->{'morn'} . "<br>";
}
In your query string you have the value metric&cnt=3 this is what you want for days to be extracted if you get from cnt=10 you will have 10 results. No need for a for loop.
With the curl_exec you'll get a json as a string, you have to parse it first to use it.
Try this: http://php.net/manual/en/function.json-decode.php
And don't forget to set the second parameter to true if you want the result as an array.
the result is JSON that you should parse with json_decode first
edit with more code:
...
$result = json_decode($result,true);
for ($i=0; $i <3 ; $i++) {
foreach ($result['list'] as $value) {
echo $value['temp']['day'];
echo $value['temp']['min'];
...
curl_exec with the option CURLOPT_RETURNTRANSFER set to true will return the result of fetch the url you have set so your variable $result is a STRING.
You hace to convert to an array:
$cSession = curl_init();
curl_setopt($cSession,CURLOPT_URL,"http://api.openweathermap.org/data/2.5/forecast/daily?q=dhaka%2Cbangladesh&mode=json&units=metric&cnt=3");
curl_setopt($cSession,CURLOPT_RETURNTRANSFER,true);
curl_setopt($cSession,CURLOPT_HEADER, false);
$result = curl_exec($cSession);
curl_close($cSession);
$result = json_decode($result,true);
//echo $result;
//$i = 3 as i am requesting 3 day data
for ($i=0; $i <3 ; $i++) {
foreach ($result as $value) {
echo $value['temp'][0]['day'];
echo $value['temp'][0]['min'];
echo $value['temp'][0]['max'];
echo $value['temp'][0]['night'];
echo $value['temp'][0]['eve'];
echo $value['temp'][0]['morn'];
}
}

PHP: Pulling JSON data out of database and displaying it

I'm using a php library from https://sourceforge.net/p/wowarmoryapi/home/Home/. It pulls json data from battle.net and stores it in my database for cache reasons.
code to get json from db (I'm not sure if it's still considered json at this point):
$data = $con->query('SELECT Data FROM wa_guilds');
I use the following code to see the data:
foreach($data as $row) {
echo "<span style='color:#ff0099'>";
var_dump($row);
echo "</span>"; }
which looks like this minus the errors, that's from another code:
I've tried various methods, mostly from this site to show my data in a way that's easy to read but I always get error.
This is definitely an object. if (is_object($data)) { echo "yay!"; } <--this works
Once I use $decodedjson = json_decode($data); it's no longer an object and I can't seem to print the results to see what it looks like. var_dump($decodedjson) returns NULL
Finally, when I use the following code:
foreach ($data as $da){
echo $da['Data']['character']['name']; }
returns Warning: Illegal string offset 'character'
and:
foreach ($data as $da){
echo $da['character']['name']; }
returns Notice: Undefined index: character
I don't understand what I'd doing wrong, or right. Do I need to somehow turn $data into a string?
NEW CODE
$sth = $con->query('SELECT Data FROM wa_guilds');
$sth->execute();
$data = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach($data as $row) {
foreach($row as $r) {
$myData = json_decode($r, true);
echo "<span style='color:#ff0099'>";
var_dump($myData['Data']);
echo "</span>"; } }
NEW ERROR
NULL NULL
From the warning I'm guessing you're using PDO. If $con is your PDO instance representing a connection to a database, try the following:
$sth = $con->prepare('SELECT Data FROM wa_guilds');
$sth->execute();
$data = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach($data as $row) {
$myData = json_decode($row['Data'], true);
echo "<span style='color:#ff0099'>";
// $myData should now be a PHP array which you can access easily
print_r($myData);
echo "</span>";
}
You will need to convert the json string first, I'm not sure how many rows you are expecting from the DB but if it's only one you don't need the loop:
$data = $sth->fetchAll(PDO::FETCH_ASSOC);
$decoded = json_decode($data['Data'], true);
echo "<span style='color:#ff0099'>";
var_dump($decoded);
echo "</span>";
if you need a loop it should work like this:
foreach($data as $d)
{
$decoded = json_decode($d['Data'], true);
echo "<span style='color:#ff0099'>";
var_dump($decoded);
echo "</span>";
}

Categories