PHP get mysql table info function - php

I am making a PHP function to return an array of a mysql database's table's info. I am new to coding in php and am looking for more efficient way to do the same thing I have done because my method does not seem very efficient. Would this be a good place to use a mysql join statement?
Here is my function.
public static function getAllTables()
{
// Get an array of all the tables in the database
$sql = "SHOW TABLES";
//this makes a connection to mysql database using mysqli
$mysqlConnection = new CMySqlConnection();
$result = $mysqlConnection->mysqli->query($sql);
$tablesArray = array();
while($row = $result->fetch_row()) {
$tablesArray[$row[0]]=array();
}
$result->close();
//Get an array of all the table names in database
$arrayKeys = array_keys($tablesArray);
//foreach table get the column's info
foreach($arrayKeys as $key){
$sql=" SHOW COLUMNS from " . $key;
$result = $mysqlConnection->mysqli->query($sql);
for($i = 0; $row = $result->fetch_row(); $i++) {
//format the array to use a descriptive key rather than a number
$row['columnName'] = $row[0];
$row['type'] = $row[1];
$row['null'] = $row[2];
$row['key'] = $row[3];
$row['default'] = $row[4];
$row['extra'] = $row[5];
unset($row[0]);
unset($row[1]);
unset($row[2]);
unset($row[3]);
unset($row[4]);
unset($row[5]);
// put the column info into the tables array
$tablesArray[$key][$i] = $row;
}
$result->close();
}
$mysqlConnection->Disconnect();
// return the tables array
return $tablesArray;
}
Thanks for any input :)

You can just query the INFORMATION_SCHEMA. They are virtual tables which contain information about your database: http://dev.mysql.com/doc/refman/5.5/en/information-schema.html
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES;
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='schema' AND TABLE_NAME='table';

Related

Why does my while loop seems to always be false

I've been trying to make my php code to show entries from my mysql database. I wanted to make it automatic in a sense that i wouldn't need to print the tables manually instead they would be printed according to an alogrythm, but it doesn't work like intended.
I've tried different ways of setting up the table but none of them worked, the furthest I got was to print one entry from the table, and spitting errors after it.
$base = $_POST["base"];
$connection = mysqli_connect("localhost","login","pass") or die("Impossible to connect to the database!");
$db = mysqli_select_db($connection, "database")or die("Impossible to download the database!");
$sql = "SELECT * FROM $base";
$mysqli_result = mysqli_query($connection, $sql);
$sql2 = "SHOW COLUMNS FROM $base";
$set1 = mysqli_query($connection, $sql2);
$colu = array();
while($db = mysqli_fetch_row($set1)){
$colu[] = $db[0]; }
$columns=implode("<br/>",$colu);
echo "<TABLE BORDER=1>";
echo "<TR><TH>$colu[0]</TH><TH>$colu[1]</TH><TH>$colu[2]</TH><TH>$colu[3]</TH><TH>$colu[4]</TH><TH>$colu[5]</TH></TR>";
while ($row = mysqli_fetch_array($set1)) {
$colu[0] = $row["echo $colu[0]"];
$colu[1] = $row["echo $colu[1]"];
$colu[2] = $row["echo $colu[2]"];
$colu[3] = $row["echo $colu[3]"];
$colu[4] = $row["echo $colu[4]"];
$colu[5] = $row["echo $colu[5]"];
echo "<TR><TD>$colu[0]</TD><TD>$colu[1]</TD><TD>$colu[2]</TD><TD>$colu[3]</TD><TD>$colu[4]</TD><TD>$colu[5]</TD></TR>";}
echo "</TABLE>";
mysqli_free_result($mysqli_result);
mysqli_close($connection); ?>
the $_POST[$base]; part works, Im guessing the issue is in the while loop as it doesnt complete once, and I'm lost as to why it doesnt want to work.
I see some problems in you script. If you want to fetch columns as heading and the content for the table body you are using the wrong result sets.
// next line make it possible to do sql insertion, and what if $base has no input?
$base = $_POST["base"];
// the die will never be reached
$connection = mysqli_connect("localhost","login","pass") or die("Impossible to connect to the database!");
$db = mysqli_select_db($connection, "database")or die("Impossible to download the database!");
// where is this query for?
$sql = "SELECT * FROM $base";
// where is this result being used
$mysqli_result = mysqli_query($connection, $sql);
$sql2 = "SHOW COLUMNS FROM $base";
$set1 = mysqli_query($connection, $sql2);
$colu = [];
// what if the table order chages? Best to use mysqli_fetch_assoc
while($db = mysqli_fetch_row($set1)){
$colu[] = $db[0];
}
// where do you use $comumns?
$columns = implode("<br/>", $colu);
echo "<TABLE BORDER=1>";
echo "<TR><TH>$colu[0]</TH><TH>$colu[1]</TH><TH>$colu[2]</TH><TH>$colu[3]</TH><TH>$colu[4]</TH><TH>$colu[5]</TH></TR>";
// you already fetched all record from set1
while ($row = mysqli_fetch_array($set1)) {
$colu[0] = $row["echo $colu[0]"];
$colu[1] = $row["echo $colu[1]"];
$colu[2] = $row["echo $colu[2]"];
$colu[3] = $row["echo $colu[3]"];
$colu[4] = $row["echo $colu[4]"];
$colu[5] = $row["echo $colu[5]"];
echo "<TR><TD>$colu[0]</TD><TD>$colu[1]</TD><TD>$colu[2]</TD><TD>$colu[3]</TD><TD>$colu[4]</TD><TD>$colu[5]</TD></TR>";
}
echo "</TABLE>";
mysqli_free_result($mysqli_result);
mysqli_close($connection); ?>
This biggest issue you have right now is this:
$base = $_POST["base"]
$sql = "SELECT * FROM $base";
$sql2 = "SHOW COLUMNS FROM $base";
This is a huge SQL Injection vulnerability, even if they pass just an empty string to this it's all bad. For example that would result in a query error and depending on your settings on the server and for error reporting, you may expose quite a bit of info. Just one example is a stack trace could contain DB passwords etc.
Instead of directly using user input make a whitelist like this:
$tables = ['user', 'user_meta', 'states']; //etc
$base = !empty($_POST["base"]) && false !== ($index = array_search($_POST["base"], $tables)) ? $tables[$index] : false;
if(!$base) die('Unknown table '.$_POST["base"]);
This way you are only using data you know the value of.
Variable reuse
Other then that, your variable names are causing a bunch of "code confusion". This is what happens if you have to generic of a variable name. Some examples:
$db = mysqli_select_db(...)
while($db = mysqli_fetch_row($set1)){ //overwriting db
...
}
//....................
while ($row = mysqli_fetch_array($set1)) {
$colu[0] = $row["echo $colu[0]"]; //overwriting $colu
This last one is also wrong because the row key will be something like:
$colu[0] = $row["echo name"];
Or something with a column name. Because you are re-using this variable ("variable confusion" ) on the next loop it will be the value of $row["echo $colu[0]"]; which will get put back into that. So lets assume this is correct without the echo and will use Name as the value.
//loop 1
$colu[0] = 'name';
$row['name'] = 'Tom';
//result
$colu[0] = 'Tom'
//loop 2
$colu[0] = 'Tom';
$row['Tom'] doesn't exist.
//result
$colu[0] = null; //undefined index warning
Cursor Reuse
You are also reusing the DB cursor $set1 and looping over it 2 times. I'm not sure about MySqli, but PDO won't allow you to do that. This is probably why the second loop is failing. I believe the second one should be $mysqli_result. It's a bit confusing because you do both queries then loop though one then the other. Instead of doing a query, looping through it. Then doing the other, and looping though that.
Instead you can do something like this:
//you can even query the DB for the table names
$tables = ['user', 'user_meta', 'states']; //etc
$base = !empty($_POST["base"]) && false !== ($index = array_search($_POST["base"], $tables)) ? $tables[$index] : false;
if(!$base) die('Unknown table '.$_POST["base"]);
$connection = mysqli_connect("localhost","login","pass") or die("Impossible to connect to the database!");
$db = mysqli_select_db($connection, "database")or die("Impossible to download the database!");
//---------query for the columns
$sql = "SHOW COLUMNS FROM `$base`";
$mysqli_result = mysqli_query($connection, $sql);
$columns = [];
while($row = mysqli_fetch_row($mysqli_result)){
$columns[] = $row[0];
}
//---------query for the data
//use the column result in the select part of query, because the column names
//come from the DB they are safe to use.
$sql = "SELECT `".implode('`,`', $columns)."` FROM `$base`"; //reuse sql (no longer needed)
$mysqli_result = mysqli_query($connection, $sql); //reuse results (no longer needed)
//fetch all data as assoc array. because we tied it to the results
//of the first query, the column names. We no longer need to map it.
$data = mysqli_fetch_all($mysqli_result, MYSQLI_ASSOC);
///output table and headers
echo "<table>";
echo "<thead>";
echo "<tr>";
//we can just loop over the columns and put them in the table head
foreach($columns as $key ){
echo "<th>$key</th>";
}
echo "</tr>";
echo "</thead>";
echo "<tbody>";
//loop over each row of data
foreach($data as $row){
echo "<tr>";
//loop over each "correlated" column
foreach($columns as $key ){
echo "<td>{$row[$key]}</td>";
}
echo "</tr>";
}
echo "</tbody>";
echo "</table>";
BONUS For getting the table names from the DB:
$sql = 'SELECT `TABLE_NAME` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` LIKE "'.$database.'"';
$mysqli_result = mysqli_query($connection, $sql);
$tables = mysqli_fetch_all($mysqli_result, MYSQLI_NUM);
Hope that makes sense.

Use PHP loop to fetch tables data from the table which contain names of database tables

I have table named category which contain names of other tables in the same database. I want to fetch table names from category table and then fetch data from each table from db. So far I have this code below:
$db = new mysqli('localhost', 'root', '', 'db_cat');
if($db){
// $q = "SELECT TABLE";
// $echo = $db->query($q);
// echo $echo;
// $result = $db->query("SHOW TABLES");
$qCat="SELECT * FROM product_category";
$cat_query= $db->query($qCat) or die(mysql_error());
while ($fetch= $cat_query->fetch_object())
{
$cat_id=$fetch->id;
$category=$fetch->category;
$p_cat=str_replace(" ","_",strtolower($category).'_categories');
//if(strlen($category)>22){$fine_product_name= substr($service, 0,19).'...';}else{ $fine_product_name=$category;}
$result = $db->query("SHOW TABLES");
while($row = $result->fetch_array()){
$tables[] = $row[0];
}
}
The second query must be different.
$result = $db->query("SELECT * FROM $category");
while($row = $result->fetch_array()){
$tables[] = $row[0];
}
print_r($tables);
First of all your design to connect to a database is not that good, Please check the below code for a proper way of connecting to it.
<?php
$con=mysqli_connect("localhost","root","","db_cat");
//servername,username,password,dbname
if (mysqli_connect_errno())
{
echo "Failed to connect to MySql: ".mysqli_connect_error();
}
?>
Here is a sample code of getting data from a table ( where this table name is in another table).
$get_table_name ="SELECT TableName FROM table_name";
$get_name=mysqli_query($con,$get_table_name);
$count=0;
while($row_name=mysqli_fetch_array($get_name)){
$count++;
$tbName=$row_name['TableName'];
$_SESSION['table_name'][count]=$tbName;
}
This will show you how to fetch data from one table. You can use a For loop to get all the tables
$table=$_SESSION['table_name'][1];
$get_table ="SELECT * FROM $table";
.... // Normal way of fetching data
You can try to adjust your code according to this and improve it.
For further reference please refer http://php.net/manual/en/book.mysqli.php

Sorting PHP arrays

I have three MySQL tables that I need to query for all of the rows. Upon getting all of the rows from each table, I need to create a multidimensional array whereby each index of that array contains only value from each of the tables. What I have right now works. But, something is telling me that there has got to be a better way of accomplishing this.
$tables = array('table_one', 'table_two', 'table_three');
$final = array();
foreach($tables as $table) {
$sql = "SELECT * FROM ".$table."";
$query = mysqli_query($con, $sql)or die(mysqli_error($con));
$num = mysqli_num_rows($query);
$i = 0;
while($row = mysql_fetch_array($query)) {
$id[$i] = $row['user_id'];
$i++;
}
for($i=0;$i<$num;$i++) {
if(!is_array($final[$i])) {
$final[$i] = array($id[$i]);
} else {
array_push($final[$i], $id[$i]);
}
}
}
The end results is something that looks like this
$final = array(array('table_one_row_one_val', 'table_two_row_one_val', 'table_three_row_one_val'),
array('table_one_row_two_val', 'table_two_row_two_val', 'table_three_row_two_val'),
array('table_one_row_three_val', 'table_two_row_three_val', 'table_three_row_three_val')
);
I get the gut felling that this could be done much more effectively, but I'm not sure how.
Thanks,
Lance
You can make your code simpler if you make your query more explicit in selecting the columns you want in the order you want them. So for example:
$sql = 'SELECT table_one.user_id as u1, table_two.user_id as u2, table_three.user_id as u3 FROM ' . implode(',', $tables);
Then each row of your result set will have the columns in the proper order making the construction of your arrays less involved. For example:
$query = mysqli_query($con, $sql)or die(mysqli_error($con));
while($row = mysql_fetch_array($query)) {
$final[] = array($row['u1'], $row['u2'], $row['u3']);
}
There may be issues with the order and relationships of the data in these arrays (especially if all 3 tables don't have the same number of rows), but working just off the information above, this is another way you could approach it. Something to think about anyway.
Try this:
$sql = "SELECT 'user_id' FROM ".$table;
What about:
$tables = array('table_one', 'table_two', 'table_three');
$final = array();
foreach($tables as $tableIndex => $table) {
$sql = "SELECT user_id FROM ".$table;
$query = mysqli_query($con, $sql)or die(mysqli_error($con));
$i = 0;
while($row = mysql_fetch_array($query)) {
$final[$tableIndex][$i] = $row['user_id'];
$i++;
}
}
It is always better selecting only the columns you will use. SELECT * is not a good SQL practice.

display all cells in a mysql column

I need all values from a table column put into an assoc array. I am having trouble finding the answer.
the table is only six rows deep.
example:
|--id--|--name--|--A--|--B--|--C--|
|--01--|--xl33--| 1.30| 2.45| 4.40|
i would like to get an assoc array for column B
name[xl33]=2.45
name[xl34]=....and so on
The trick is that the form will tell the script which column to fetch. A,B,C,D,E,F OR G
I know i could re-format the table and accomplish what i want but I need it structured the way i have it.( i have left out some columns for simplicity)
function return_column($letter){
$result = mysql_query("SELECT name, $letter FROM example") or die(mysql_error());
while($row = mysql_fetch_assoc( $result )) {
$return[$row['name']] = $row[$letter];
}
return $return;
}
$results = return_column('A');
print_r($results);
Something like :
$col = 'B';
$name = array();
$result = mysql_query("SELECT * FROM table") or die(mysql_error());
while ($row = mysql_fetch_array($result)) {
$name[$row['name']] = $row[$col];
}
This creates an array $name and uses the name column as the key and the $col column for the value ...
You are looking for the mysql_fetch_assoc() function.
Example/
$query = $this->query($YOUR_QUERY);
$returnMap = array();
while ($row = mysql_fetch_assoc($query)) { array_push($returnMap, $row); }
Use mysql_fetch_assoc — Fetch a result row as an associative array.
while ($row = mysql_fetch_assoc($result)) {
$data[$row["column1"]]= $row["column2"];
..............
.........
}

Strange PHP output

I'm using this code to attempt to grab a table name and store it in a variable.
<?php
connectDB();
$sql = "SHOW TABLES";
$result = mysql_query($sql);
$tables = mysql_fetch_array($result);
foreach ($tables as $table) {
$table_name = $table[0];
echo $table_name;
}
closeConn();
?>
For one, its outputting 'aa' and 'bb' if i change the array index which i know arent table names in the db and two, what i want to do is run some code for every table in the db and insert the table name into a variable which i can use in said code? How would i do that?
$tables = mysql_fetch_array($result);
mysql_fetch_array fetches one row, not the entire set. This means that when you do $table[0], you are actually working on the string value of each field in the row.
You should put the mysql_fetch_array inside the loop instead:
while ($table = mysql_fetch_array($result)) {
$table_name = $table[0];
echo $table_name;
}
SHOW TABLES returns a table with one table name per row. You should use mysql_fetch_array as many times as there are rows in the table, because it only retrieves one row of the table...
Think of something like this:
while($row = mysql_fetch_array($result)) {
$table_name = $row[0];
// ...
}
$sql = "SHOW TABLES";
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result, MYSQL_BOTH))
{
$tables[] = $row[0];
}
// To Display
foreach ($tables as $table) {
$table_name = $table;
echo $table_name;
}

Categories