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>";
}
Related
I have this code to show how may times a champion was picked in a tournament for example ("Gragas : 2 Times" , "Syndra :4 times" , etc)
I'm using api from leaguepedia to recieve the informations
but im stucked right now, I'm having a problem when "echoing" my table to show the results.
So I want that "qtd" be by the "pick" side (Image1) and if there's an easy way to show what I want.
// $Result is a CURL coming from leaguepedia api
$result = json_decode($file_contents);
// Double foreach to access the values from leaguepedia api
foreach ($result as $d) {
foreach ($d as $data) {
// $data->title->Team1Picks is coming from league pedia api as a string separated by "," Ex:("Gragas,Shen,Maokai,etc")
// So I need to explode to an array to count.
$picks[] = explode(",", $data->title->Team1Picks);
}
}
// $mostpicked is an array for me to count how many times a champion was picked
// $f is an array to see the names of the picked champions
foreach ($picks as $pick) {
foreach ($pick as $total) {
$mostPicked[] = $total;
$f[] = $total;
}
}
// Basically here I'm counting how many times a champion was picked Ex : ("Gragas:2","Syndra:4" ,etc)
asort($mostPicked);
$mostPicked = array_count_values($mostPicked);
$name = array_unique($f);
asort($name);
// Foreach to get all unique names from the picks Ex : ("Gragas","Shen",etc) instead of ("Gragas , "Gragas" , etc)
foreach ($name as $champ) {
echo "<tr>";
echo "<td>" . $champ . "</td>";
echo "</tr>";
}
// This foreach to get the number of times a pick was made Ex : ("Gragas 2 Times")
foreach ($mostPicked as $pick) {
echo "<tr>";
echo "<td>" . $pick . "</td>";
echo "</tr>";
}
Here you go, this should do it.
// Hero name => pick count
$heroPicks = array();
foreach ($result as $d) {
foreach ($d as $data) {
//$data->title->Team1Picks is coming from league pedia api as a string separated by "," Ex:("Gragas,Shen,Maokai,etc")
// So i need to explode to an array to count.
$picks = explode(",", $data->title->Team1Picks);
foreach ($picks as $pick) {
$pick = trim($pick);
if (!array_key_exists($pick, $heroPicks)) {
$heroPicks[$pick] = 0;
}
$heroPicks[$pick] += 1;
}
}
}
uasort($heroPicks, function($a, $b) {
return $a - $b;
});
$heroPicks = array_reverse($heroPicks);
echo "Best picks:".PHP_EOL."<br />";
foreach ($heroPicks as $heroName => $pickCount) {
echo $heroName." - ".$pickCount.PHP_EOL."<br />";
}
It seems because you're putting the $pick in a new <tr>
Try adjusting your loops so that you're building an array of $champ=>$qtd then you an iterate over that and build your table as desired.
I'm trying to identify whether I am looking at the first column in the array.
I haven't tried anything, but googled plenty and cannot find a solution.
while($row = mysqli_fetch_row($sql)) {
echo '<tr>';
foreach ($row as $col) {
if () //NEED CODE HERE
echo "<td><a href = 'https://whatismyipaddress.com/ip-lookup' target = '_blank'>$col</a></td>";
}
echo '</tr>';
}
mysqli_fetch_row fetches "one row of data from the result set and returns it as an enumerated array, where each column is stored in an array offset starting from 0 (zero)." So the key of the column is the same as column order.
So you can do this:
while($row = mysqli_fetch_row($sql)) {
echo '<tr>';
foreach ($row as $key => $col) {
if ($key === 0) {
echo "<td><a href = 'https://whatismyipaddress.com/ip-lookup' target = '_blank'>$col</a></td>";
}
}
echo '</tr>';
}
But column is subjected to changes in database structure and SQL query changes. I would personally prefer mysqli_fetch_assoc or mysqli_fetch_object so I can use the column by name instead of order number. Its less error prone. For example,
while($row = mysqli_fetch_assoc($sql)) {
echo '<tr>';
foreach ($row as $key => $col) {
if ($key === 'ip_address') {
echo "<td><a href = 'https://whatismyipaddress.com/ip-lookup' target = '_blank'>$col</a></td>";
}
}
echo '</tr>';
}
Note: $sql here should be a mysqli_query result instead of the actual SQL string.
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
I tried to create a table that calculating the data which stored in mutli-dimensional arrays' value and show the result by table format.
I don't know how to count the values which stored in the array's array(third level array's value.
Can I using the function to count values in the mutli-dimensional arrays' value? Hope anyone can teach me, thanks.
<?php
$itemList = array
("book"=>array("ID"=>"14567",
"name"=>array("History"=>array("American"=>12,"Europe"=>2), "SF"=>array("Space"=>32), "Chinese"=>array("kungFu"=>10))),
"stationary"=>array("ID"=>"24547", "name"=>array("HB"=>array("ABC"=>123, "MC"=>161,"GCD"=>26)))
);
$item = "<table border=1>";
$item .= "<td>item count(s)</td>";
foreach($itemList as $key => $value){
$item .= "<tr>";
$item .= "<td align=center>" .
/*count the categories of the items(e.g. American,Europe,Space,Kungfu show
the result: "4")*/
. "</td>";
$item .= "</tr>";
}
$item .= "</table>";
echo $item;
?>
foreach($itemList['book']['name'] as $key => $value)
{
foreach ($itemList['book']['name'][$key] as $key1 => $value1) {
$category[] = $key1;
$value2[] = $value1;
}
}
echo count($category);
here you got the total numebr of count of your category
below is example how mine arrays do look, i want them combine so i can output both title, votes and ratings in one line.
foreach ($items->items as $item) {
echo $item->title;
foreach ($results->resx as $res) {
echo $res->votes;
echo $res->ratings;
}
I'd like to have this, but i know this isn't right.
foreach ($items as $item) ($results as $res) {
echo $res->votes;
echo $res->ratings;
echo $item->title;
}
You can use array_merge() for that, like so:
foreach (array_merge($results, $items) as $item) {
echo isset($item->title) ? $item->title : $item->votes .'<br>'. $item->ratings;
}
UPDATE:
Changed how to print values as the objects from merged array can only have one of the two groups of properties.
UPDATE 2:
After some OP's notes that made more clear what his scenario is, and now given the assumption that both $results and $items arrays have the same number of elements, an update solution is as follows:
while ((list(, $it) = each($items)) && (list(, $rs) = each($results))) {
echo $it->title;
echo $rs->votes;
echo $rs->ratings . '<br>';
}