Show only columns with values as result of a dynamic sql-query - php

I have an html form to read out data from an sql-database. According to the selected criteria, the results are shown in a dynamically generated table. This works well with the following code. The SELECT query is composed according to the selected criteria.
$sql = "SELECT DISTINCT $selection FROM $tabelle WHERE $whereclause";
$result = mysqli_query($db, $sql) or die("<b>No result</b>"); //Running
the query and storing it in result
$numrows = mysqli_num_rows($result); // gets number of rows in result
table
$numcols = mysqli_num_fields($result); // gets number of columns in
result table
$field = mysqli_fetch_fields($result); // gets the column names from the
result table
if ($numrows > 0) {
echo "<table id='myTable' >";
echo "<thead>";
echo "<tr>";
echo "<th>" . 'Nr' . "</th>";
for($x=0;$x<$numcols;$x++){
$key = array_search($field[$x]->name, $custom_column_arr);
if($key !== false){
echo "<th>" . $key . "</th>";
}else{
echo "<th>" . $field[$x]->name . "</th>";
}
}
echo "</tr></thead>";
echo "<tbody>";
$nr = 1;
while ($row = mysqli_fetch_array($result)) {
echo "<tr>";
echo "<td>" . $nr . "</td>";
for ($k=0; $k<$numcols; $k++) { // goes around until there are no
columns left
echo "<td>" . $row[$field[$k]->name] . "</td>"; //Prints the data
}
echo "</tr>";
$nr = $nr + 1;
} // Ende der while-Schleife
echo "</tbody></table>";
}
}
mysqli_close($db);
Now, I want to display only those columns that contain at least one value and not those with NULL, 0, empty string or empty. My problem is, that $numcols counts the empty columns, too.

Related

How can I get data with column names in the same table from SQL using PHP?

I'm trying to show a full table from SQL in my HTML/PHP webpage. So far I succeeded to fetch the data from the table in my webpage without define each row in HTML. This works, but it shows the data from the table only. I want to see the column names in the first row.
See my code below:
include_once "connection.php";
$sql = "SELECT * FROM `own`";
$result = mysqli_query($conn, $sql);
echo "<br>";
echo "<table border='1'>";
while ($row = mysqli_fetch_assoc($result))
{
echo "<tr>";
foreach($row as $value) {
echo "<td>" . $value . "</td>";
}
echo "</tr>";
}
echo "</table>";
As you are using mysqli_fetch_assoc() - this will return an array with the column names as the key for each value. So this code will display (for the first loop only) the column names as a separate row.
$headerDisplayed = false;
while ($row = mysqli_fetch_assoc($result))
{
if ( $headerDisplayed == false ) {
echo "<tr>";
foreach($row as $columnName => $value) {
echo "<th>" . $columnName . "</th>";
}
echo "</tr>";
$headerDisplayed = true;
}
echo "<tr>";
foreach($row as $value) {
echo "<td>" . $value . "</td>";
}
echo "</tr>";
}
If you want to be able to give a more meaningful name, you could also use column aliases (for example)..
select `dept_no` as `department number` from `departments`
will show department number as the heading instead of dept_no.
The easiest solution would be to just output the column names first on the first iteration:
while ($row = mysqli_fetch_assoc($result))
{
// If the variable $colNamesPrinted is undefined, print the column names
if (isset($colNamesPrinted) === false) {
echo "<tr>";
foreach($row as $name => $value) {
echo "<th>" . $name . "</th>";
}
echo "</tr>";
// Define the variable so it will be set on the next iteration.
$colNamesPrinted = true;
}
echo "<tr>";
foreach($row as $value) {
echo "<td>" . $value . "</td>";
}
echo "</tr>";
}

How to convert from mysqli to PDO with function that hides empty columns

I have an html-form to read out data from a DB that are then dislayed in an html-table. Columns that contain no values should not be displayed. This works well with the following code using array_column and array_filter:
$sql = "SELECT DISTINCT $selection FROM $table WHERE $where";
$result = mysqli_query($db, $sql) or die("<b>No results</b>"); //Running the query and storing it in result
$numrows = mysqli_num_rows($result); // gets number of rows in result table
$numcols = mysqli_num_fields($result); // gets number of columns in result table
$field = mysqli_fetch_fields($result); // gets the column names from the result table
$custom_column_arr = array('Color' => 'color_comment', 'Weight' => 'weight_comment');
if($numrows > 0) {
echo "<table id='myTable'>";
echo "<thead>";
$results = array();
while($row = mysqli_fetch_assoc($result)) {
$results[] = $row;
}
echo "<tr>";
echo "<th>" . 'Nr' . "</th>";
for($x = 0; $x < $numcols; $x++) {
$column[$x] = array_column($results, $field[$x]->name); // puts all existing values of a column into the field-name
if(array_filter($column[$x])) { // displays only those columns with at least one value in it
$key = array_search($field[$x]->name, $custom_column_arr);
if($key !== FALSE) {
echo "<th>" . $key . "</th>";
} else {
echo "<th>" . $field[$x]->name . "</th>";
}
}
}
echo "</tr></thead>";
echo "<tbody>";
$nr = 1;
$result = mysqli_query($db, $sql);
while($row = mysqli_fetch_array($result)) {
echo "<tr>";
echo "<td>" . $nr . "</td>";
for($k = 0; $k < $numcols; $k++) { // goes around until there are no columns left
$column[$k] = array_column($results, $field[$k]->name); // puts all existing values of a column into the field-name
if(array_filter($column[$k])) { // displays only those columns with at least one value in it
echo "<td>" . $row[$field[$k]->name] . "</td>"; //Prints the data } } echo "</tr>"; $nr = $nr + 1;
} // End of while-loop
echo "</tbody></table>";
}
}
mysqli_close($db);
}
Due to security reasons, I switched to PDO prepared statements to avoid SQL-injection:
enter code here
$sql = "SELECT DISTINCT $selection FROM $table WHERE color = :color AND weight = :weight";
$stmt = $pdo->prepare($sql);
$renalstatus = '10';
$bindValue = implode("/n ", $bindValue);
$stmt->bindValue(':color', $color, PDO::PARAM_STR);
$stmt->bindValue(':weight', $weight, PDO::PARAM_INT);
$stmt->execute();
$zeilen = $stmt->rowCount();
$spalten = $stmt->columnCount();
if($zeilen > 0) {
echo "<table id='myTable'>";
echo "<thead>";
$results = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$results[] = $row;
}
echo "<tr>";
echo "<th>" . 'Nr' . "</th>";
for($x = 0; $x < $spalten; $x++) {
$column[$x] = array_column($results, $fields[$x]->name); // puts all existing values of a column into the field-name
if(array_filter($column[$x])) { // displays only those columns with at least one value in it
$key = array_search($fields[$x], $custom_column_arr);
if($key !== FALSE) {
echo "<th>" . $key . "</th>";
} else {
echo "<th>" . $fields[$x] . "</th>";
}
}
}
echo "</tr></thead>";
echo "<tbody>";
$nr = 1;
$stmt = $pdo->query($sql);
while($row = $stmt->fetch(PDO::FETCH_NUM)) {
echo "<tr>";
echo "<td>" . $nr . "</td>";
for($k = 0; $k < $spalten; $k++) { // goes around until there are no columns left
$column[$k] = array_column($results, $fields[$k]->name); // puts all existing values of a column into the field-name
if(array_filter($column[$k])) { // displays only those columns with at least one value in it
echo "<td>" . $row[$k] . "</td>"; //Prints the data}
}
echo "</tr>";
$nr = $nr + 1;
} // End of while-loop
echo "</tbody></table>";
}
}
$stmt->close();
The query results are correctly displayed as before. However, completely empty columns are displayed as well and shoul be hidden.
After having built the headline, in mysqli there is a second query before the rows are generated:
$result = mysqli_query($db, $sql);
Unfortunately, using PDO this does not work with:
$stmt = $pdo->query($sql); or $stmt->execute();
I would be more than happy if someone could help me make this function work again!

How to integrate array_column() and array_filter() into dynamic table generation of sql results

I want to read out data from an sql-database an show them in a table. This works well. Now, I would like to show only those columns with at least one value in it and not the empty ones (containing NULL, 0, empty string). This works with the following example:
enter code here
<TABLE width="500" border="1" cellpadding="1" cellspacing="1">
<?php
$query = mysql_query("SELECT * FROM guestbook", $db);
$results = array();
while($line = mysql_fetch_assoc($query)){
$results[] = $line;
$Name = array_column($results, 'Name');
$Home = array_column($results, 'Home');
$Date = array_column($results, 'Date');
$Emptycolumn = array_column($results, 'Emptycolumn');
$Comment = array_column($results, 'Comment');
$City = array_column($results, 'City');
}
echo "<TR>";
if(array_filter($Name)) {echo "<TH>Name</TH>";}
if(array_filter($Home)){echo "<TH>Home</TH>";}
if(array_filter($Date)){echo "<TH>Date</TH>";}
if(array_filter($Emptycolumn)){echo "<TH>Emptycolumn</TH>";}
if(array_filter($Comment)){echo "<TH>Comment</TH>";}
if(array_filter($City)){echo "<TH>City</TH>";}
echo "</TR>";
$query = mysql_query("SELECT * FROM guestbook", $db);
while($line = mysql_fetch_assoc($query)){
echo "<TR>";
if(array_filter($Name)) {echo "<TD>".$line['Name']."</TD>";}
if(array_filter($Home)) {echo "<TD>".$line['Home']."</TD>";}
if(array_filter($Date)) {echo "<TD>".$line['Date']."</TD>";}
if(array_filter($Emptycolumn)) {echo "<TD>".$line['Emptycolumn']."</TD>";}
if(array_filter($Comment)) {echo "<TD>".$line['Comment']."</TD>";}
if(array_filter($City)) {echo "<TD>".$line['City']."</TD>";}
echo "</TR>";
}
?>
</TABLE>
Since the column-names of my table are highly variable (depending on the query), the table is generated by looping through the result-array, first the column-names, then the values in the rows:
enter code here
$sql = "SELECT DISTINCT $selection FROM $tabelle WHERE
$whereclause"; //will be changed to PDO
$result = mysqli_query($db, $sql) or die("<b>No result</b>"); //Running
the query and storing it in result
$numrows = mysqli_num_rows($result); // gets number of rows in result
table
$numcols = mysqli_num_fields($result); // gets number of columns in
result table
$field = mysqli_fetch_fields($result); // gets the column names from the
result table
if ($numrows > 0) {
echo "<table id='myTable' >";
echo "<thead>";
echo "<tr>";
echo "<th>" . 'Nr' . "</th>";
for($x=0;$x<$numcols;$x++){
$key = array_search($field[$x]->name, $custom_column_arr);
if($key !== false){
echo "<th>" . $key . "</th>";
}else{
echo "<th>" . $field[$x]->name . "</th>";
}
}
echo "</tr></thead>";
echo "<tbody>";
$nr = 1;
while ($row = mysqli_fetch_array($result)) {
echo "<tr>";
echo "<td>" . $nr . "</td>";
for ($k=0; $k<$numcols; $k++) { // goes around until there are no
columns left
echo "<td>" . $row[$field[$k]->name] . "</td>"; //Prints the data
}
echo "</tr>";
$nr = $nr + 1;
} // End of while-loop
echo "</tbody></table>";
}
}
mysqli_close($db);
Now, I tried to integrate the array_column() and array_filter()-blocks of the example above into the loops, but unfortunately, it didn´t work. I´m sure, this is easy for a professional and I would be very grateful, if someone could help me with this problem!
Thank you very much in advance!!

Gather Table Names + Data using mysqli and php

I am trying to get the column names and data from a table using mysqli and php. Any help is appreciated.
I know how to do this in java by more or less this code:
String [] header= new String[numberOfColumns-1];
//Code to get column names in header array
String table = "<table><tr>"
for(int i=0;i<numberOfColumns-1;i++){
table= table + "<td>" + header[i] + </td>;
}
table = table + </tr>;
while(result.next()!=null){
table = table + <tr>
for (int j = 0 ; j < numberOfColumns-1 ; j++){
table = table + <td> + result.getString[j] + </td>
}
table = table + </tr>
}
But i have no idea how to do it in php. Each table is different but what i have to far for the one table:
include("config.php");
session_start();
$sql = ($_POST['q']);
$result = mysqli_query($db,$sql);
echo "<tr>";
echo "<td>First Name</td>";
echo "<td>Last Name</td>";
echo "<td>Date of Birth</td>";
echo "<td>Contact Details</td>";
echo "</tr>";
while($rowitem = mysqli_fetch_array($result,MYSQLI_ASSOC)){
echo "<tr>";
echo "<td>" . $rowitem['fname'] . "</td>";
echo "<td>" . $rowitem['lname'] . "</td>";
echo "<td>" . $rowitem['dob'] . "</td>";
echo "<td>" . $rowitem['contact'] . "</td>";*/
echo "</tr>";
}
echo "</table>"; //end table tag
EDIT: Is the implementation of the fetch_fields correct?
include("config.php");
session_start();
$sql = ($_POST['q']);
$result = mysqli_query($db,$sql);
$finfo = mysqli_fetch_fields($result);
echo "<tr>";
foreach ($finfo as $val) {
echo "<td>" . $val->name . "</td>"
}
echo "</tr>";
while($rowitem = mysqli_fetch_array($result,MYSQLI_ASSOC)){
echo "<tr>";
for($x =0; $x < count($finfo);$x++){
echo "<td>" . $rowitem[$x] . "/td";
}
echo "</tr>";
}
echo "</table>";
EDIT 2: Database Connection.php
<<?php
include("config.php");
session_start();
$sql = ($_GET['q']);
$result = mysqli_query($db,$sql);
echo "<table border='1' class='table_info'>";
$finfo = mysqli_fetch_fields($result);
echo "<tr>";
foreach ($finfo as $val) {
echo "<td>" . $val->name . "</td>";
}
echo "</tr>";
while($rowitem = mysqli_fetch_array($result,MYSQLI_ASSOC)){
echo "<tr>";
foreach ($row as $value) { (line 18)
echo "<td>" . $value . "</td>";
}
echo "</tr>";
}
echo "</table>"; //end table tag
?>
Error:
Notice: Undefined variable: row in databaseConnection.php on line 18
Warning: Invalid argument supplied for foreach() in databaseConnection.php on line 18
You can call mysqli_fetch_fields on the $result object, and retrieve the name property for each object in the returned array. See documentation for examples.
There are a couple ways to do this:
Use array_keys() to grab the names of the keys from an associative array:
$rowitem = mysqli_fetch_array($result, MYSQLI_ASSOC);
$header = array_keys($rowitem);
Use mysqli_fetch_fields() to grab the field objects, and parse out the names into an array using array_map():
// Helper function to use in array_map
// (For PHP < 5.3. If >= 5.3.0, use the second version)
function getFieldName($field) { return $field->name; }
// For PHP < 5.3:
$header = array_map("getFieldName", mysqli_fetch_fields($result));
// For PHP >= 5.3.0:
$header = array_map(function($o) { return $o->name; }, mysqli_fetch_fields($result));
As mentioned you can use $result->fetch_fields() to get the field information from the result and this includes the name of each field.
For what you're trying to acheive this code should work for pretty much any table/query:
<?php
/* Connect to mysql */
$mysqli = new mysqli("localhost", "username", "password", "database");
/* Check connection */
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
/* Your query */
$query = "SELECT * from table";
if ($result = $mysqli->query($query)) {
/* Output HTML table */
echo "<table border='1'>";
/* Get field information for all returned columns */
$finfo = $result->fetch_fields();
/* Output each column name in first table row */
echo "<tr>";
foreach ($finfo as $val) {
echo "<td>".$val->name."</td>";
}
echo "</tr>";
/* Fetch the result and output each row into a table row */
while($row = mysqli_fetch_array($result, MYSQLI_NUM)) {
echo "<tr>";
foreach ($row as $value) {
echo "<td>" . $value . "</td>";
}
echo "</tr>";
}
$result->free();
echo "</table>";
}
$mysqli->close();
(Obviously you should never query a database from a $_POST variable without some serious sanitisation of the input, but I'll assume that was just for your convenience.)
You can Echo in a table..
$result = mysqli_query($db,$sql)
if (!$result) {
die("Query to show fields from table failed");
}
$fields_num = mysqli_num_fields($result);
echo "<table border='1'><tr>";
// printing table headers
for($i=0; $i<$fields_num; $i++)
{
$field = mysqli_fetch_field($result);
echo "<td>{$field->name}</td>";
}
echo "</tr>\n";
// printing table rows
while($row = mysqli_fetch_row($result))
{
echo "<tr>";
// $row is array... foreach( .. ) puts every element
// of $row to $cell variable
foreach($row as $cell)
echo "<td>$cell</td>";
echo "</tr>\n";
}
mysqli_free_result($result);`

Writing the attributes of a database in PHP

I am writing an application in which user can enter a database name and I should write all of its contents in table with using PHP.I can do it when I know the name of database with the following code.
$result = mysqli_query($con,"SELECT * FROM course");
echo "<table border='1'>
<tr>
<th>blablabla</th>
<th>blabla</th>
<th>blablabla</th>
<th>bla</th>
</tr>";
while($row = mysqli_fetch_array($result))
{
echo "<tr>";
echo "<td>" . $row['blablabla'] . "</td>";
echo "<td>" . $row['blabla'] . "</td>";
echo "<td>" . $row['blablabla'] . "</td>";
echo "<td>" . $row['bla'] . "</td>";
echo "</tr>";
}
echo "</table>";
In this example I can show it since I know the name of table is course and it has 4 attributes.But I want to be able to show the result regardless of the name the user entered.So if user wants to view the contents of instructors there should be two columns instead of 4.How can I accomplish this.I get the table name with html.
Table:<input type="text" name="table">
Edit:Denis's answer and GrumpyCroutons' answer are both correct.You can also ask me if you didnt understand something in their solution.
Quickly wrote this up, commented it (This way you can easily learn what's going on, you see), and tested it for you.
<form method="GET">
<input type="text" name="table">
</form>
<?php
//can be done elsewhere, I used this for testing. vv
$config = array(
'SQL-Host' => '',
'SQL-User' => '',
'SQL-Pass' => '',
'SQL-Database' => ''
);
$con = mysqli_connect($config['SQL-Host'], $config['SQL-User'], $config['SQL-Pass'], $config['SQL-Database']) or die("Error " . mysqli_error($con));
//can be done elsewhere, I used this for testing. ^^
if(!isSet($_GET['table'])) { //check if table choser form was submitted.
//In my case, do nothing, but you could display a message saying something like no db chosen etc.
} else {
$table = mysqli_real_escape_string($con, $_GET['table']); //escape it because it's an input, helps prevent sqlinjection.
$sql = "SELECT * FROM " . $table; // SELECT * returns a list of ALL column data
$sql2 = "SHOW COLUMNS FROM " . $table; // SHOW COLUMNS FROM returns a list of columns
$result = mysqli_query($con, $sql);
$Headers = mysqli_query($con, $sql2);
//you could do more checks here to see if anything was returned, and display an error if not or whatever.
echo "<table border='1'>";
echo "<tr>"; //all in one row
$headersList = array(); //create an empty array
while($row = mysqli_fetch_array($Headers)) { //loop through table columns
echo "<td>" . $row['Field'] . "</td>"; // list columns in TD's or TH's.
array_push($headersList, $row['Field']); //Fill array with fields
} //$row = mysqli_fetch_array($Headers)
echo "</tr>";
$amt = count($headersList); // How many headers are there?
while($row = mysqli_fetch_array($result)) {
echo "<tr>"; //each row gets its own tr
for($x = 1; $x <= $amt; $x++) { //nested for loop, based on the $amt variable above, so you don't leave any columns out - should have been <= and not <, my bad
echo "<td>" . $row[$headersList[$x]] . "</td>"; //Fill td's or th's with column data
} //$x = 1; $x < $amt; $x++
echo "</tr>";
} //$row = mysqli_fetch_array($result)
echo "</table>";
}
?>
$tablename = $_POST['table'];
$result = mysqli_query($con,"SELECT * FROM $tablename");
$first = true;
while($row = mysqli_fetch_assoc($result))
{
if ($first)
{
$columns = array_keys($row);
echo "<table border='1'>
<tr>";
foreach ($columns as $c)
{
echo "<th>$c</th>";
}
echo "</tr>";
$first = false;
}
echo "<tr>";
foreach ($row as $v)
{
echo "<td>$v</td>";
}
echo "</tr>";
}
echo "</table>";
<?php
$table_name = do_not_inject($_REQUEST['table_name']);
$result = mysqli_query($con,'SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME='. $table_name);
?>
<table>
<?php
$columns = array();
while ($row = mysql_fetch_assoc($result)){
$columns[]=$row['COLUMN_NAME'];
?>
<tr><th><?php echo $row['COLUMN_NAME']; ?></th></tr>
<?php
}
$result = mysqli_query($con,'SELECT * FROM course'. $table_name);
while($row = mysqli_fetch_assoc($result)){
echo '<tr>';
foreach ($columns as $column){
?>
<td><?php echo $row[$column]; ?></td>
<?php
}
echo '</tr>';
}
?>
</table>

Categories