How to create HTML tables from MySQL? [duplicate] - php

This question already has answers here:
Creating dynamic tables in HTML using MySQL and PHP
(2 answers)
Closed 15 days ago.
I'm building a part of a system where the user can define "views" from a mysql database.
I want some way of generating simple HTML tables/reports from the data, but not just plain output of sql queries- simple joins probably isn't enough.
Any ideas?
Just to be clear: I know perfectly well how to create a HTML table with PHP/MySQL - that is the simple part. What I want to do is allow my USERS to create their own tables without being exposed to the process!
Right, i'll give some more details- thanks for all the responses:
Currently users can create tables using a wizard, then view/edit/delete records in these tables. This makes it difficult to give an example as tables could change. The data I expect the client to input is for renting houses- a table of houses, tenants, rooms, maintenance issues etc.
What I aim to enable the user to do is to create some basic formatted output of a particular view, for example "show rent turnover in the current month for all houses" or "show overdue tenants" or "show rooms with no tenants". Once set up, these will only be viewed, not edited, so the process just has to be bearable to set up.
Does that make sense? If it's not possible I'll just hard-code the views- just makes the system less flexible!

Is this what you're looking for? It will dynamically generate an html table from a mysql result no matter what or how big the result.
//this function dynamically outputs a basic HTML table from any mysql result
function createTable($result) {
$table = '<table><tr>';
for ($x=0;$x<mysql_num_fields($result);$x++) $table .= '<th>'.mysql_field_name($result,$x).'</th>';
$table .= '</tr>';
while ($rows = mysql_fetch_assoc($result)) {
$table .= '<tr>';
foreach ($rows as $row) $table .= '<td>'.$row.'</td>';
$table .= '</tr>';
}
$table .= '<table>';
//mysql_data_seek($result,0); //if we need to reset the mysql result pointer to 0
return $table;
}
This is how you'd print the table:
echo createTable($result);

You can use phpMyAdmin to show MySQL in nice tables or if you want to code it yourself you can use PHP and HTML to do the work:
<table>
<?php
mysql_connect("localhost", "mysql_user", "mysql_password") or
die("Could not connect: " . mysql_error());
mysql_select_db("mydb");
$result = mysql_query("SELECT id, name FROM mytable");
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
?>
<tr>
<td><?=$row['id']; ?></td>
<td><?=$row['name']; ?></td>
</tr>
<?
}
mysql_free_result($result);
?>
</table>
Edit: After reading your edits, it may not be the best idea to make users "create their own tables", but instead to give them a number of options and sort orders to create a better user experience. Otherwise it's just a form with some input elements and some if statements.

You'll have to expose users to part of the process, since they have to describe the tables and table relationships somehow. You could take a page from the likes of Crystal Reports, Visual Studio and phpMyAdmin and create a visual table designer. A table is represented as a rectangle with a title bar showing the table's name and a list of fields. The tables are on a canvas, and can be placed anywhere on that canvas. Foreign keys are represented as lines connecting fields.
You can use the same interface as a query creator: the user specifies which tables to query by dragging them from a list of tables to the canvas, which fields they're interested in (perhaps include a checkbox next to each column) and which fields to join on by connecting fields with lines. To join a table to itself, you could allow a table to be added to a query more than once, or allow fields within a table to be connected to other fields within the same table.
If you don't have it, grab phpMyAdmin, install it, open a database and go to the "Designer" tab to see how it works. You can also take a look at some screenshots

You have to define the way users will create those HTML tables. Do they setup a number of rows and columns, then feed the table manually ?
Once we had to do a templating system where all images, css properties, positionning of various html blocks, etc. The whole system was 5 or 6 mysql tables just to store the templates properties, but if it's just a table you can ease the process.
Imagine one mysql table for table format and properties (row count, col count, col width, colors, etc.) and another mysql table for data to put inside. This second table should have columns for storing date, row and col positions.
The rest is all making a form accessible to non-tech users to configure and feed table, and render table with some PHP loops and queries.

Approximately 100% of websites does the same task: create HTML tables from SQL database.
So, you can get yourself some PHP/Mysql book to get an idea.
Though all tables being hardcoded by a programmer.
As for the user-defined views it can be a bit more complicate. But possible too

<?php
$query="SELECT * FROM table_name";
$result=mysql_query($query);
$numfields = mysql_num_fields($result);
echo "<table border=1><tr>";
for ($i=0; $i < $numfields; $i++) // Header
{ echo '<th>'.mysql_field_name($result, $i).'</th>'; }
echo "</tr>";
while
($res=mysql_fetch_row($result)) //you may use mysql_fatch_array($result) which can hendel both $res[name] and $res[1]
{
echo"
<tr>
<td> $res[0]</td>
<td> $res[1]</td>
<td> $res[2]</td>
.
.
.
</tr>";
}
echo"</table>";
?>
100% Working just changed.
$query variable according to your table

Related

Inventory system multiple tables and recipes

I'm a novice in PHP and extremely new to databases, so forgive me if this is a stupid question:
I've built an inventory system in PHP/MySQL that allows someone to (among other things) add raw materials to a table, that has "Price_Per_Pound_In_Dollars" and "Pounds_In_Stock" columns. As it stands, updating the "Pounds-In-Stock" column for a raw material must be done manually, one-at-a-time via a form.
I'm now wanting to add another database for recipes that contains the steps needed for making a product, so that the "Pounds_In_Stock" column can be updated for multiple raws at once. Please see the image below.
Basically someone would go to a form, pick a product from a drop down menu (populated with recipe names by doing a mysqli_query), enter the number of gallons they want to make and press submit.
The rows in the recipe table have the figures needed for making a gallon of that product, so all of the numbers in the table would be multiplied by the number that was entered into the form.
So, if someone were to choose "Recipe Name 1" and entered "2" into the gallons input box. It would multiply the "Pounds_Needed_Per_Gallon" by 2 and put that info into a mysqli_query to remove it from the correct raw "Pounds_In_Stock" column in the "Raws" table. (If that makes sense).
Now my question:
Is it possible to do this dynamically? Am I approaching this the wrong way? I know I can get the result I want by hard coding the values for each recipe in a PHP document and linking to it via the "action =" on the form page, but this seems like an exceedingly inelegant way of doing things. I just can't seem to wrap my head around how to do this with MySQL.
Form Issue:
I created a bare-bones form that should include the table names in a drop-down menu (so that a recipe table can be selected). But I can't seem to get the table names to echo out in the drop down. I know the while loop is working correctly, since there are three options in the drop-down menu, which corresponds to the number of tables in the database, the only problem is that they're blank. Please see the image and code below. I looked over my code a few times, but can't see where I made a mistake. Any ideas?
<?php
//Prepare MySQL Query.
$Product_Menu_Query ="SHOW TABLES";
$Run_Product_Menu_Query = mysqli_query($Connect, $Product_Menu_Query);
?>
<form action="submit.php" method="POST">
<span>Recipe Name:</span><br>
<select name="recipe">
<?php //Populates dropdown with Product_Name from database.
while ($row = mysqli_fetch_array($Run_Product_Menu_Query)) {
echo '<option value="' . $row[0] . '">' . '</option>';
}
?>
</select><br><br>
<span>Gallons:</span><br>
<input type="number" name="gallons"><br><br>
<input type="submit" value="Submit">
</form>
Screenshot of form:
looks like you would have something like this (change your table names and fields accordingly to your database actual field and table names):
$recipeName = $_POST['recipe'];
$gallons = $_POST['gallons'];
$stmt = $mysqli->prepare("SELECT raws.id as rawId, (recipe.pounds_needed_per_gallon * ?) as gallons
FROM RecipeName recipe
JOIN Raws raws on recipe.raw_id=raws.raw_id
WHERE raws.raw_name = ?");
$stmt->bind_param("ds", $gallons, $recipeName);
$stmt->execute();
$stmt->bind_result($rawId, $gallonsNeeded);
$stmt->close();
mysqli_query("UPDATE Raws set pounds_in_stock = (pounds_in_stock - $gallonsNeeded) where id = $rawId");
EDIT: I see you need more help with debugging. You should check the values obtained through the queries (i.e. rawId and gallonsNeeded) and echo out errors, but as i don't have your entire code base I cannot tell exactly what is going wrong with your code.

Creating a site to query a database of tables

I have a small problem. I am working with some manual testers who are untrained in programming/database design. Our current process means that these manual testers need to insert data into our database at certain times whilst we build a GUI to facilitate this in the future.
In the interim, I would like to create a simple site. What I would like to do with the site is, simply, connect to our database, allow the manual tester to enter some keywords, and return any columns within tables that are close/related to the keywords provided. This would save a lot of time for our testers searching for colums in our (rather large) database.
How could I create a site like this? I think it could be useful for a lot of people, so I have decided to post the question up here to gather the thoughts of StackOverflow.
At the moment, I am thinking a simple PHP page with a textbox, which allows the user to enter some data, separated by commas. Explode the data based on commas, hold it in an array. Connect to my database, then use the Information Schema View to retrieve column information.
My main problem is - what is the most effective way to use the Information Schema View to retrieve columns related to the keywords entered by the users ? How can I ensure the columns returned are the most suitable?
Any input here would be greatly appreciated. Thanks a lot.
Tl;dr is the bolded part, for busy people :)
I think you could achieve this with a simple form and some ajax calls using on key up.
Here is a simple example in which the list will update each time the user enters a letter in the column name they are searching for.
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript">
$(document).ready(function() {
$("#faq_search_input").keyup(function()
{
var faq_search_input = $(this).val();
var dataString = 'keyword='+ faq_search_input;
if(faq_search_input.length>1)
{
$.ajax({
type: "GET",
url: "ajax-search.php",
data: dataString,
success: function(server_response)
{
document.getElementById("searchresultdata").style.display = "block";
$('#searchresultdata').html(server_response).show();
}
});
}return false;
});
});
</script>
</head>
<body>
<div class="searchholder">
<input name="query" class="quicksearch" type="text" id="faq_search_input" />
<div id="searchresultdata" class="searchresults" style="display:none;"> </div>
</div>
</body>
</html>
next we need a script to carry out our search
ajax-search.php
//you must define your database settings
define("DB_HOST", "FOO");
define("DB_USERNAME", "BAR");
define("DB_PASSWORD", "YOUR PASSWORD");
define("DB_NAME", "DATABASE NAME");
if(isset($_GET['keyword']))
{
$search = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);
if ($search->connect_errno)
{
echo "Failed to connect to MySQL: (" . $search->connect_errno . ") " . $search->connect_error;
$search->close();
}
$keyword = trim($_GET['keyword']) ;
$query ="SELECT COLUMN_NAME FROM ".DB_NAME.".INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME LIKE '%".$keyword."%'";
$values = $search->query($query);
if($values->num_rows != 0)
{
while($row = $values->fetch_assoc())
{
echo $row['COLUMN_NAME']."<br>";
}
}
else
{
echo 'No Results for :"'.$_GET['keyword'].'"';
}
}
As the user types out a column name all of the column name like this will be returned and updated on the fly, without page reload. Hope this helps
You should do something like this:
Form:
<form action="search.php" method="post">
<textarea name="words"></textarea>
<input type="submit">
</form>
search.php
<?php
// You will need a DB user with enough permissions
$link = mysqli_connect($server,$user,$pass);
mysqli_select_db($link,$database_name);
print "<table>";
// Comma separated
$words = explode(",",$_POST['words']);
foreach ($words as $word)
{
$sql = "SELECT COLUMN_NAME FROM ".$database_name.".INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%".$word."%'";
$res = mysqli_query($link,$sql);
while ($row = mysqli_fetch_assoc($res))
{
print "<tr><td>".$row['COLUMN_NAME']."</td></tr>";
}
}
print "</table>";
?>
I can see why you are asking this interesting question. If the tester enters a list of keywords, and you use the information schema view to obtain a list of matching columns, then there is a danger that there will be a lot of false matches that could waste time or cause the tester to enter incorrect information into your system. You want to know how to determine which columns are the best matches to the tester's query. But you want to keep it simple because this is just a temporary workaround, it's not your main application.
The answer is to supplement search results using a reputation-based system. Here is a very simple one that should work well for your application.
First, create two simple tables to store rating information for the tables and columns in your database. Here is the starting structure.
TEST_SEARCH_TABLES:
TABLE_ID
TABLE_NAME
RATING
TEST_SEARCH_COLUMNS:
COLUMN_ID
TABLE_ID
COLUMN_NAME
RATING
Populate TEST_SEARCH_TABLES with the name of every table in your database. Populate TEST_SEARCH_COLUMNS with the name of every column, and link it to the corresponding table. Initialize all the RATING columns to 1000.0 - you will be using the Elo Rating System to supplement your rankings because it is simple, easy to implement and it works great.
When the user enters a list of keywords, don't use Information Schema View. Instead, search the TEST_SEARCH_COLUMNS table for any columns that have any of those keywords. Assign each column a WEIGHT based on the number of hits. (For example, if the search is "customer,amount,income" then a column CUSTOMER_ID would have a weight of 1. A column CUSTOMER_INCOME would have a weight of 2, and CUSTOMER_INCOME_AMOUNT would have a weight of 3.) Calculate the WEIGHT of each table as the sum of the weights of its columns.
Now for each table and column returned by your search, multiply the WEIGHT times the RATING to determine the SEARCH VALUE. Give the tester a list of matching tables in descending order of search value. Within each table, also list the columns in descending order of their search value.
Every time a table or column appears in a search, use the Elo Rating System to give it a WIN against an opponent rated 1000.0. Every time a user selects a column to work with, give both that column and its table a win against an opponent rated 1500.0. In this way, the most useful and successful tables and columns will organically float to the top of your search lists over time.
A side benefit to this approach (using tables instead of information schema view) is that this approach is more extensible. As an enhancement, you could put DESCRIPTION and COMMENTS columns on the TEST_SEARCH_TABLES and TEST_SEARCH_COLUMNS tables, and also search those columns for keyword matches as well.
Here is another optional enhancement - you could put a (+) and (-) button next to each table and column and give it a win against a 2000-rated opponent if the user clicks (+) and a loss against a zero-rated opponent if the user clicks (-). That will allow your testers to vote for columns they find important and to vote against columns that are always getting in the way.
I'm not sure if I fully understood your issue
Take a look at this:
http://php.net/manual/en/function.mysql-list-tables.php
you can get all the tables on a database , store them in an array then filter them using your keywords
I think this could be done in the following steps without any PHP programming and even without need in any web-server.
Write SQL-script which makes everything to retrieve data you need.
Modify script to add columns to result set with simple html-formatting to make you result record like the following:
'<tr><td>', 'resultcolumn1', '</td><td>', 'resultcolumn2','</td></tr>'
Run this script using sqlcmd with output option to file. Give resulting file .html extension.
Place sqlcmd call inside cmd file. After calling sqlcmd call web browser with resulting html file name as parameter. This will display your results to tester.
So, your testers only run cmd file with some parameters and get html page with results. Of course you need to form correct html head and body tags, but this is not a problem.
Now about your main question about how you can be sure the columns returned are the most suitable. I think the most reliable from the most simple ways is to create thesaurus table which contains synonyms for your column names. (This could be done by testers themselves). So you can search your column names from Information Schema View using LIKE in INFORMATION_SCHEMA.COLUMNS as well as in thesaurus table.
Not sure if you want spend time on writing and supporting your solution. For php/mysql I would use http://www.phpmyadmin.net/home_page/index.php or if users can access db directly
http://dev.mysql.com/downloads/gui-tools/5.0.html
Might take some time to tech them how to use it, but will save a lot of problems in a long run.
Another thing, you can create *.sql files that would populate db automatically.
query.sql
CREATE TABLE "example" (
"id" INT NOT NULL AUTO_INCREMENT,
"name" VARCHAR(30),
"age" INT
);
INSERT INTO "example" VALUES
('1', 'a', 1),
('2', 'b', 2);
than you can run it from command line:
mysql -u USER -pPASSWORD database_name < filename.sql
Use mysql_connect method if you use mysql and enter data like:
INSERT INTO tablename
and stuff just read about it.

How to allocate one ID to another and show this in HTML

For my iPhone web app I have created a database in php MyAdmin, it contains two tables (bookings, waiters and allocations) the I wish to view the bookings within a table in HTML where i can allocate a waiter to that booking. Any tips on how this would be done, any help will be appreciated as this is my first contact with web app development and MyAdmin. Thanks!
Mysql work with autoincrement id. You will have an id after of an insertion. You can to create a table only to id's and after to use it in the insertion of the waiter.
First you will need to get the data from the table via MySQL
$sql = "SELECT * FROM table_name";
$result = mysql_query($sql);
Then you would loop through the result
while($row = mysql_fetch_assoc($result)){
extract($row);
}
Then you can do as you wish with the returned data...
You really need to give us a little more... What have you got so far?

Simple ORM in PHP MySQL update joined tables

I'm currently trying to write a simple ORM with PHP and mysql. I want the orm class to be able to work with joined tables.
So here's my problem, the following code shows how I map the data the query yields into an array.
public function execute_query($db_connection)
{
$query = '';
foreach($this->sql_query as $query_part)
$query .= $query_part;
$result = $db_connection->query($query);
while($row = $result->fetch_assoc())
{
array_push($this->m_Data, $row);
}
}
db_connection is a mysqli object.
sql_query contains all the different query parts (e.g. sql_query['join'] etc.).
m_Data is the array that contains the data read from the db.
My specific problem now is when I'm using a join statement in my query this function will just override fields with the same name in my m_Data array. Also if I dont save the name's of the table the specific field data is coming from, I later can't update the tables with the same join statement.
tl,dr. I need to be able to not only save the table data like this: m_Data{ 'field_name' => 'value' } but I also need to save the table name the field is selected from. I could then save the data like this m_Data{ 'table_name.field_name' => 'value' } which enables me later to generate a query to update the joined tables successfully.
I cant seem to find any information on how to get the origin table name for each field I pull out of the result.
If it isnt possible with mysqli I'd much appreciate it if you point me in the right direction.
extra short problem statement:
I need to get a result set and read each row seperatly. For each row I need the following information for every field selected: field_name, table_name, value.
There must be a simple answer to this but I seem to be searching for the wrong keywords to find a solution.
I hope I've written this understandable enough.
Seems to me that you should store table column values in an object, so if you have a related table, the column values would be stored in a separate object - and so would not interfere with the values in your primary table.
In general you might work with the ORM this way:
// Make joined query
$rows = ...
foreach($rows as $row)
{
// $row just refers to the primary table
echo $row->id;
// You get a many:1 related table this way
echo $row->getRelatedRow()->value;
// You get a 1:many rows this way
$rows = $row->getOtherRelatedRows();
}
Depending on how you set up your query options, getting related data may or may not initiate further SELECTs to get the required data.
mysqli_result::fetch_fields has useful things:
http://www.php.net/manual/en/mysqli-result.fetch-fields.php
table
orgtable
field type
etc

php mysql - document retrieveal and display

I built a document upload admin screen, where my client can browse and upload pdf documents to a mysql dbase.
I have two separate tables for the Agendas, and one for Minutes. both have separate table names "upload" and "upload_mins".
on the index.php page, I have the page fetch each row of the database, and display all of the valid documents on a "download" page.
I have come a across a problem.
Each dbase is set to increment ID. now that there is two databases, they are coming to utilize the same ID.
so I am pulling from the Agenda table:
http://www.example.com/clerk.php?ID=77
and I am pulling from the Minutes table also:
http://www.example.com/clerk.php?ID=77
and they happen to have the same increment ID.
Is there some way to avoid this? Can I add a field parameter to the minutes to make sure that they don't have the same URL when pulling documents?
Create a integer field, or txt field?
i.e. http://www.example.com/clerk.php?ID=77&min=yes
If these are just documents, you could store them in a single table but have a column called type that differentiates between minutes and agendas. That way, IDs will be unique.
You could also extend the types column be a foreign key to a types table, so you can extend it to include additional document types such as spreadsheets in the future easily.
This would also aid the front-end display, as you would only need one query to fetch the documents within a batch or timeframe, but add them to differing arrays. For example:
// get the last 20 uploaded documents
$sql = "SELECT * FROM documents ORDER BY created DESC LIMIT 0,20";
$res = mysql_query($sql);
while ($doc = mysql_fetch_object($res)) {
$type = $doc->type;
if (!isset($docs[$type]) || !is_array($docs[$type])) {
$docs[$type] = array();
}
$docs[$type][] = $doc;
}
// loop over agendas
foreach ($docs['agendas'] as $agenda) {
echo '' . $agenda->title . '';
}
// loop over minutes
foreach ($docs['minutes'] as $minutes) {
echo '' . $minutes->title . '';
}
...
You say that the problem you are having is with URLs being duplicated. You have 2 different options to solve that.
The first is to create an identifier that tells you which table you want. You could have agenda.php and minutes.php, or you could have clerk.php?ID=77&type=1 and clerk.php?ID=77&type=2.
This will allow you to know which table you are referencing. This is also the approach I would recommend. There is no reason to avoid duplicate keys in different tables as long as you have a way of knowing which table you need.
The second option is to put all your records into a single table. You can then add a type column that specifies what type of document it is. You can then leave your clerk.php file alone, but need to change the upload page to populate the type column.
If you are just storing PDFs in the database, you shouldn't need anything in this table except id, type, and the document itself.

Categories