PHP code to separate Table based on column values - php

I have a csv file that should be converted to HTML table based on column values , and I have to put the values into separate table based on first column of csv . And I think the problem is because of '\n' in first column.
So its like this:
Here in Result column, in one row I have three values separated using comma (W,M,P). In the code I wrote it is considered as separate table headers .
Can anyone please help me with this?
This is my code:
<?php
$csv="FinalResult.csv" ;
$csvcontents=file_get_contents($csv);
$csv_array = explode("\n", $csvcontents);
$tables = [];
foreach($csv_array as $key => $value) {
if ($key == 0) {
continue;
}
$line = explode(',', $value);
if (array_key_exists($line[0], $tables)) {
$tables[$line[0]][] = $line;
} else {
$tables[$line[0]] = [$line];
}
}
foreach ($tables as $key => $value) {
echo '<h1> ' .$key. ' </h1>'; // YOUR TITLE (Team)
echo "<table>";
echo '<tr>';
foreach (explode(',', $csv_array[0]) as $keyHeader => $valueHeader) {
if (in_array($keyHeader, [0, 1])) {
continue;
}
echo "<th>$valueHeader</th>";
}
echo '</tr>';
foreach ($value as $keyRow => $valueRow) {
echo '<tr>';
foreach ($valueRow as $keyValue => $valueValue) {
if (in_array($keyValue, [0, 1])) {
continue;
}
echo "<td>$valueValue</td>";
}
echo '</tr>';
}
echo '</table>';
}
?>
I refereed in stack overflow , but there they were giving only single values to a column and not providing multiple values .
But am getting output like this ,
so it takes the value of Result column after '-' as a new heading , i tried but am not able to solve this , can anyone really help me in this matter .
Here is how my output should look like:
I marked in yellow where all the data am getting in same column
This is my csv file :
Team,Date,Opponent,Result
MIN,May-03,UTA,a.b.c=d-e.f-g.h=log4j2-i.xml-j -k -a4j.k=tp_r-RR.xml -
MIN,May-04,SEA,"L,Q,J"
SAC,May-03,DAL,L
SAC,May-04,TOR,W
NYN,May-05,BAL,L
NYN,May-07,MIA,W

Here is the code
<table>
<?php
$csvValues= array_map('str_getcsv', file('FinalResult.csv'));
$counter = 0;
// Header
echo "<tr>";
foreach($csvValues[0] as $headers){
echo "<th>".$headers."</th>";
}
echo "</tr>";
// Content
foreach($csvValues as $values){
echo "<tr>";
if($counter >0){
foreach($values as $data){
echo "<td>".$data."</td>";
}
}
echo "</tr>";
$counter++;
}
?>
</table>

Related

Foreach with Table - PHP and Leaguepedia API

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.

PHP Add New Line to Array Values Inside One Row and Column in Database Table

I managed to add multiple data in one column in the database, but now I need to display it with a new line in the browser so they don't stick with each other as I display them as an array in one column.
Here is my code:
if (isset($_GET['id']) && $_GET['id'] == 5) {
$subArray = array("StudentAnswer");
$subId6 = $db->get("answertable", null, $subArray);
foreach ($subId6 as $sub) {
$answers[] = $sub['StudentAnswer'] . "\n";
}
foreach ($answers as $row) {
$answers2 = explode("||", $row[0]);
foreach($answers2 as $row2){
$answers3 = $row2 . '\n';
}
}
$db->where('AccessId', $_GET['token']);
$db->where('StudentAnswer', $answers3);
$subId8 = $db->get("answertable");
if ($subId8) {
echo json_encode($subId8);
}
}
You are overriding $subId6 after getting its content. Try to fetch the table $rows in a new variable and the extract the content from it, like the code below.
<?php
// Example of $subId6 content
$subId6 = array(["StudentAnswer" => ["Answer 1\nAnswer 2\nAnswer 3"]], ["StudentAnswer" => ["Answer 1\nAnswer 2\nAnswer 3"]]);
// Fetch rows
foreach ($subId6 as $sub) {
$rows[] = $sub['StudentAnswer'];
}
// Decode rows
foreach($rows as $row) {
$answers = explode("\n", $row[0]);
echo "New answers: \n";
// Split answers in single answer
foreach ($answers as $answer)
echo "$answer \n";
echo "\n";
}
You will have a list of all the answers split for table rows
If you want a string of answers seperated by a space then simply do
if (isset($_GET['id']) && $_GET['id'] == 5) {
$subId6 = $db->get("answertable");
foreach ($subId6 as $sub) {
$answers .= $sub['StudentAnswer'] . ' ';
}
$answers= rtrim($answers, ' '); //remove last space in case thats an issue later
$db->where('AccessId', $_GET['token']);
$db->where('StudentAnswer', $answers);
$subId8 = $db->get("answertable");
if ($subId8) {
echo json_encode($subId8);
}
}

identifying column number in PHP mysqli_fetch_row() WHILE loop

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.

Filter JSON array with objects inside in PHP

I have a particular JSON file that looks like this:
[
{
"objID":"kc6BvvNlVW",
"string":"bill",
"createdOn":"2018-09-18T01:51:02",
"updatedOn":"2018-09-18T01:51:02",
"number":1,
"boolean":true,
"array":["item1","item2"],
"pointer":{"type":"__pointer","objID":"hYtr54Ds","className":"Users"}
},
{
"objID":"sS1IwFPPWh",
"string":"tom",
"createdOn":"2018-09-18T01:59:40",
"updatedOn":"2018-09-18T01:59:40",
"number":12.3,
"boolean":false,
"array":["item1","item2"],
"pointer":{"type":"__pointer","objID":"tRe4Fda5","className":"Users"}
}
]
1. I need to first check if the "pointer" object has "__pointer" inside the type key and show only the objID value in an HTML table, like this:
"tRe4Fda5"
Right now, this is how my table looks like:
And here's my foreach PHP code (into a table row):
foreach($jsonObjs as $i=>$obj) {
$row_id = $i;
echo '<tr>';
foreach($obj as $key => $value){
// $value is an Array:
if (is_array($value)) {
echo '<td>';
foreach($value as $k=>$v){
// $v is a Pointer
if ($v === '__pointer') {
echo json_encode($v); // <-- WHAT SHOULD I DO HERE ?
// $v is an Array:
} else {
echo json_encode($v);
}
}
echo '</td>';
// $value is a Number:
} else if (is_numeric($value)){
echo '<td>'.(float)$value.'</td>';
// $value is a String:
} else { echo '<td>'.$value.'</td>'; }
}
As you can see in the pointer column, the string I get is:
"__pointer""hYtr54Ds""Users"
with no commas as separators, so this is the line of code I need to edit:
echo json_encode($v); // <-- WHAT SHOULD I DO HERE ?
I've tried with echo json_encode($v[$k]['__ponter']);, but no positive results.
So my final first question is: how can I get each VALUE of the "pointer" array?
2. Also, the second row of the boolean column shows noting since its value is false, shouldn't it show 0, since the first row shows 1 (true)?
You can look into the object during the second loop to see if it has a property called type and if that property is set to __pointer.
foreach($jsonObjs as $i=>$obj) {
$row_id = $i;
foreach($obj as $key => $value){
// see if $value has a type property that is set to pointer
if (isset($value['type']) && $value['type'] == "__pointer") {
// $value is the pointer object. Do with it what you will
echo "<td>" . $value['objID'] . "</td>";
}
// more code
}
}
instead of
foreach($value as $k=>$v){
// $v is a Pointer
use
foreach($value as $k)
{
//then check for pointer
if($k->type === '__pointer')
{
echo json_decode($k); //here you will get proper key and value
}
}

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

Categories