I'm currently updating my PHP knowledge and I've stumbled upon a problem whilst grabbing data from my database.
The problem I have in itself could probably be sorted with the max_connection setting (yes, I've searched around), but I believe it might be a work-around, since I don't want to change base settings, if not so needed.
I have three "steps" in my little "ladder";
My main is a ladder, every ladder has one (or more) step and every step has one (or more) modules.
So what I'm trying to do is a function that retrieves all of these and shows them. Now, every function has a connection to my database; where the function runs its query and then closes. My first clue was to close the database between every function, which I did - but since I'm retrieving my code "all at once", this doesn't work (see code).
How would I go about making one database connection (maybe in a function) and calling it once, and then retrieving all the information, without opening new connections?
I hope you have all information required to answer my questions, and I hope I'm posting this in a stack overflow way.
Thank you in advance.
P.S: Dunno if I used this code tool right, it looks structured, but it doesn't have highlights?
CODE:
<?php
echo displayResult();
function displayResult() {
$db = new mysqli ('localhost', 'website', 'dog', 'nplus');
$sql = 'SELECT * FROM ladders';
$result = $db->query($sql);
$r = '';
$r .= '<table>';
while ($row = $result->fetch_object()) {
$r .= '<tr>';
$r .= '<td>' . htmlspecialchars($row->ladderID) . '</td>';
$r .= '<td>' . htmlspecialchars($row->ladderName) . '</td>';
$r .= '<td>' . htmlspecialchars($row->created) . '</td>';
$r .= displayAssociateStep($row->ladderID);
$r .= '<tr><td> </td></tr>';
}
$r .= '</table>';
$db->close();
return $r;
}
function displayAssociateStep($ladderID) {
$r = '';
$db = new mysqli ('localhost', 'website', 'dog', 'nplus');
$sql = 'SELECT * FROM steps WHERE ladderID = '. $ladderID ;
$result = $db->query($sql);
$r = '';
while ($row = $result->fetch_object()) {
$r .= '<tr>';
$r .= '<td></td>';
$r .= '<td></td>';
$r .= '<td>' . htmlspecialchars($row->stepName) . '</td>';
$r .= '<td>' . htmlspecialchars($row->created) . '</td>';
$r .= '</tr>';
}
$db->close();
return $r;
}
?>
You only need to connect to the database once, and pass it around as an argument, like so:
<?php
function displayResult($db) {
$sql = "
SELECT *
FROM ladders
";
$result = $db->query($sql);
// ADD ERROR CHECKING HERE
// What happens if the query fails?
$r = '<table>';
while ($row = $result->fetch_object()) {
$r .= '<tr>';
$r .= '<td>' . htmlspecialchars($row->ladderID) . '</td>';
$r .= '<td>' . htmlspecialchars($row->ladderName) . '</td>';
$r .= '<td>' . htmlspecialchars($row->created) . '</td>';
$r .= '</tr>';
$r .= displayAssociateStep($db, $row->ladderID);
$r .= '<tr><td colspan="3"> </td></tr>';
}
$r .= '</table>';
return $r;
}
function displayAssociateStep($db, $ladderID) {
// Are you 100% certain $ladderID is always safe to use in a query?
// Does it need escaping?
$sql = "
SELECT *
FROM steps
WHERE ladderID = $ladderID
";
$result = $db->query($sql);
// ADD ERROR CHECKING HERE
// What happens if the query fails?
$r = '';
while ($row = $result->fetch_object()) {
$r .= '<tr>';
$r .= '<td></td>';
$r .= '<td>' . htmlspecialchars($row->stepName) . '</td>';
$r .= '<td>' . htmlspecialchars($row->created) . '</td>';
$r .= '</tr>';
}
return $r;
}
// Connect once
$db = new mysqli ('localhost', 'website', 'dog', 'nplus');
// Pass the connection in as an argument
echo displayResult($db);
// Close the connection
$db->close();
I would say... pass the $db variable you got in displayResult to displayAssociateStep, as an added parameter. Then you don't need to open/close connexion in displayAssociatesStep anymore.
Is it what you want to do?
Related
I have an SQL-database where I read out data that are then shown in a dynamically generated html-table. Here is my code that works fine:
$sql = "SELECT $selection FROM $tabelle WHERE $masterarray";
$result = mysqli_query($db, $sql) or die("Invalid query");
$numrows = mysqli_num_rows($result);
$numcols = mysqli_num_fields($result);
$field = mysqli_fetch_fields($result);
if ($numrows > 0) {
echo "<table>";
echo "<thead>";
echo "<tr>";
echo "<th>" . 'Nr' . "</th>";
for($x=0;$x<$numcols;$x++){
echo "<th>" . $field[$x]->name . "</th>";
}
echo "</tr>";
echo "</thead>";
echo "<tbody>";
echo "<tr>";
$nr = 1;
while ($row = mysqli_fetch_array($result)) {
echo "<td>" . $nr . "</td>";
for ($k=0; $k<$numcols; $k++) {
echo "<td>" . $row[$k] . "</td>"; //Prints the data
}
$nr = $nr + 1;
echo "</tr>";
}
echo "</tbody>";
echo "</table>";
}
}
mysqli_close($db);
Now, I want to remove specific columns (e.g. those, which are empty or those, which are not that interesting for the user, who makes the request).
I tried it with unset($field[$variable]), however, it didn't work. In addition, the values (if there are any), should be removed, too.
can let mysql filter them out for you,
$sql = "SELECT $selection FROM $tabelle WHERE $masterarray AND LENGTH($selection) > 0";
-- http://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_length
Always format the array before you print it. Try to remove the specific columns from the $field array before you echo the HTML and then print the final table. Once the HTML code is echoed in PHP you won't be able to remove it without the use of JavaScript.
You can check against the $field[$x]->name variable and use continue to skip the column.
<?php
// DataBase Config - http://php.net/manual/pt_BR/pdo.construct.php.
$dsn = 'mysql:host=localhost;dbname=test';
$usr = 'root';
$pwd = '';
try { // try to connect in database.
$pdo = new PDO($dsn, $usr, $pwd);
} catch (PDOException $e) { // if there is error in the connection.
die('Connection failed: ' . $e->getMessage());
}
// Prepare Statement and execute - http://php.net/manual/pt_BR/pdo.prepare.php.
$stm = $pdo->prepare('select id, weight, color, name from product');
$stm->execute();
// Get ALL rows - Object.
$rows = $stm->fetchAll(PDO::FETCH_OBJ);
// Print Rows.
//echo '<pre>'.print_r(rows, true).'</pre>';
// Check $row;
if (count($rows)) {
// Order and Display Cols.
$colsDisplay = [
'id' => 'ID Product',
'name' => 'Name',
'weight' => 'Weigth'
];
// Table.
$html = '<table border="1">';
$html .= "\n <thead>";
$html .= "\n <tr>";
$html .= "\n <th bgcolor='#eee'>Row</th>";
$html .= "\n <th>". implode("</th>\n <th>", $colsDisplay) ."</th>";
$html .= "\n </tr>";
$html .= "\n </thead>";
$html .= "\n <tbody>";
// Loop ROWS.
foreach ($rows as $key => $val) {
$html .= "\n <tr>";
$html .= "\n <td bgcolor='#eee'>". $key ."</td>";
// Loop COLS to display.
foreach ($colsDisplay as $thKey => $thVal) {
$html .= "\n <td>". $val->$thKey ."</td>";
}
$html .= "\n </tr>";
}
$html .= "\n".' </tbody>';
$html .= "\n".'</table>';
echo $html;
}
In order to know that a column is empty, you should check the whole column. There are different ways to do it, one of them could be investigating which of them are empty and then only using those that aren't empty. Something like this:
<?php
// ...
$q = "SELECT SUM(LENGTH(my_first_column)) col_0, SUM(LENGTH(my_second_column)) col_1, ..., SUM(LENGTH(my_11th_column)) col_10 FROM $tabelle WHERE $masterarray";
// ... execute query and return results in $nonEmpty
$nonEmpty = array();
foreach($row as $columnIndex) {
if ($row[$columnIndex] > 0) {
$nonEmpty[] = $columnIndex;
}
}
// ... now go through results and print only cols with at least one row with lenght > 0 i.e. non empty
$len = 11;
$rowHTML = "<tr>";
while ($row = mysqli_fetch_array($result)) {
for ($i = 0; $i < $len; ++$i) {
$rowHTML = '';
if (!in_array($i, $nonEmpty)) {
$rowHTML .= '<td>' . $row[$i] . '</td>';
}
$rowHTML .= "</tr>\n";
}
}
// ...
This chunk of code will remove columns with ALL empty values. If you have at least one cell in the column with some value, you'll see the column in your result.
The code isn't optimized - it's just a rough idea. But it's a starting point.
I have this function that reads the contents of an array, and outputs data form a mysql database into a table. However, when there are duplicated in the array, it only lists that information once. In the code below, it will only give me three table rows, 1, 100 and 140. It skips over the second instance of 1. How would I fix that to output the data into the table regardless of there being duplicates?
$con = mysql_connect('localhost', 'root', 'password');
$table = "cwr";
$player1pod1 = array(1, 1, 100, 140);
function generatelistplayer1 ($player1pod1, $con, $table){
$sql = "SELECT * FROM $table WHERE id IN (".implode(',',$player1pod1).")";
$myData = mysql_query($sql, $con);
echo "<table border='1' cellpadding='2'> ";
while($row = mysql_fetch_array( $myData )) {
echo "<tr>";
echo '<td>' . $row['id'] . '</td>';
echo '<td>' . $row['cardname'] . '</td>';
echo '<td>' . $row['rarity'] . '</td>';
}
echo "</table>";
Desired output for the table is :
1
1
100
140
I'm getting :
1
100
140
It's only going to give you 3 rows, because it's only going to give you unique rows. You can instead use a UNION query if you want actual duplicates.
"SELECT * FROM $table WHERE id = 1 UNION ALL SELECT * FROM $table WHERE id IN (".implode(',',$player1pod1).")";
If you want to use the array, you can create a loop:
$query = [];
foreach($player1pod1 as $pod) {
$query[] = "SELECT * FROM $table WHERE id = $pod";
}
$sql = implode(" UNION ALL ",$query);
Fetch all the results first (into an array, key is the id), then based on your original list, display each result.
You can print the result as many times as you need in a loop.
Notice its not a loop on the query. Query to db will be done only once, and I do not recommend a solution which do multiple queries or query same data more than once.
If order is not important i.e array(1, 100, 1, 140) = is good as = array(1, 1, 100, 140) , we can use array_count_values($player1pod1) and print each result as much as needed:
$con = mysql_connect('localhost', 'root', 'password');
$table = "cwr";
$player1pod1 = array(1, 1, 100, 140);
function generatelistplayer1 ($player1pod1, $con, $table)
{
$counts = array_count_values($player1pod1);
$sql = "SELECT * FROM $table WHERE id IN (" . implode(',', $player1pod1) . ")";
$myData = mysql_query($sql, $con);
echo "<table border='1' cellpadding='2'> ";
while ($row = mysql_fetch_array($myData)) {
for ($i=0;$i<count($counts[$row['id']]);$i++) {
echo "<tr>";
echo '<td>' . $row['id'] . '</td>';
echo '<td>' . $row['cardname'] . '</td>';
echo '<td>' . $row['rarity'] . '</td>';
}
}
echo "</table>";
}
In case that the order is do important we can first collect data from the databse sql, and then to print it one by one, with "print_rows" function in my example. In this solution we don't need to count the values but we use some RAM to hold the sql results:
function generatelistplayer1 ($player1pod1, $con, $table)
{
$sql = "SELECT * FROM $table WHERE id IN (" . implode(',', $player1pod1) . ")";
$myData = mysql_query($sql, $con);
//extract data
$sql_data = array();
while ($row = mysql_fetch_array($myData)) {
$sql_data[$row['id']] = array( 'cardname'=> $row['cardname'],'rarity'=> $row['rarity']);
}
//print data
print_rows($player1pod1,$sql_data);
}
function print_rows($player1pod1, $mysql_data)
{
echo "<table border='1' cellpadding='2'> ";
for($i=0;$i<count($player1pod1);$i++) {
echo "<tr>";
echo '<td>' . $player1pod1[$i] . '</td>';
echo '<td>' . $mysql_data[$player1pod1[$i]['cardname']] . '</td>';
echo '<td>' . $mysql_data[$player1pod1[$i]['rarity']] . '</td>';
}
echo "</table>";
}
I have a function that uses mysqli function that is as follows:
public function GetProjectOptions()
{
$return = "";
$sql = "SELECT `id`, `project_name` FROM `projects`;";
$rs = static::$link->query($sql);
$return .= '<select class="form-control" name="project">';
while ($result = mysqli_fetch_assoc($rs));
{
$return .= "<option value='" . $result['id'] . "'>" .
$result['project_name'] . "</option>";
}
$return .= '</select>';
return $return;
}
The purpose of this function is to create the options and select that will be used for the Projects on my site, I know that there are 4 projects currently stored in the table, but they do not return in this function, what have I done wrong?
EDIT:
Link to screen output: (http://i.imgur.com/YIYiheH.png)
Link to code output: (http://i.imgur.com/RZsUIwQ.png)
Link to code usage: (http://i.imgur.com/4J9rvd7.png)
(Wouldn't let me do normal links)
I found the problem.
Remove the semi-colon here
while ($result = mysqli_fetch_assoc($rs));
^
that's why it's not throwing an error, because it's considered as valid syntax.
Your loop is being stopped/terminated by it.
What I think Jay and Styphon mean by their comment is that you don't do any error checking within your SELECT query. Are you sure your query is executing properly? I understand this is a relatively simple query and that you're positive there are four projects currently stored in your table, but it's always a good habit to check. Try this:
public function GetProjectOptions()
{
$return = "";
$sql = "SELECT `id`, `project_name` FROM `projects`;";
$rs = static::$link->query($sql);
$return .= '<select class="form-control" name="project">';
if($rs){
while ($result = mysqli_fetch_assoc($rs));
{
$return .= "<option value='" . $result['id'] . "'>" . $result['project_name'] . "</option>";
}
$return .= '</select>';
}else{
$message = 'Invalid query: ' . mysqli_error() . "\n";
$message .= 'Whole query: ' . $sql;
die($message);
}
return $return;
}
I hope this helps!
I'm trying to implement memcached into my server due to how large the database gets so quickly. I was wondering how I'm able to implement it into this code:
function getWorkers($db)
{
$meminstance = new Memcache();
$meminstance->pconnect('localhost', 11211);
$del = $db->prepare('SELECT DISTINCT(address) from works');
$del->execute();
$arr = $del->fetchAll();
$works = getMaxWork($db);
foreach($arr as $a)
{
$del = $db->prepare('SELECT * FROM works WHERE address = \'' . $a[0] . '\'');
$del->execute();
$work = $del->rowCount();
echo '<tr>';
echo '<td>' . htmlspecialchars($a[0], ENT_QUOTES, 'UTF-8') . '</td>';
echo '<td>' . $work . '</td>';
echo '<td>' . round(intval($work)/intval($works)*100, 2) . '</td>';
echo '</tr>';
}
}
Here you go
function getData($db)
{
$meminstance = new Memcache();
$meminstance->pconnect('localhost', 11211);
$sqlQuery = 'SELECT DISTINCT(address) from works';
$memcacheKey = md5($sqlQuery);
if ( $arr = $meminstance->get(memcacheKey) )
{
// its in cache do nothing
}
else
{
// its not in cache, so we came here, lets now get it from db and cache it
$del = $db->prepare($sqlQuery);
$del->execute();
$arr = $del->fetchAll();
$works = getMaxWork($db);
// lets now cache it
$meminstance->set(memcacheKey,$arr);
}
foreach($arr as $a)
{
$sqlQuery = 'SELECT * FROM works WHERE address = \'' . $a[0] . '\'';
$memcacheKey = md5($sqlQuery);
if ( $del = $meminstance->get($memcacheKey))
{
//its in cache yaaaaaaaa :D
}
else
{
$del = $db->prepare('SELECT * FROM works WHERE address = \'' . $a[0] . '\'');
$del->execute();
$work = $del->rowCount();
// lets cache it here
$meminstance->set($memcacheKey,$del);
}
echo '<tr>';
echo '<td>' . htmlspecialchars($a[0], ENT_QUOTES, 'UTF-8') . '</td>';
echo '<td>' . $work . '</td>';
echo '<td>' . round(intval($work)/intval($works)*100, 2) . '</td>';
echo '</tr>';
}
}
The logic when you are using memcache in your website. Is it md5 the sql queries so they will be unique. You first try to fetch from memcached, ( you md5 the sql Query) so it will be the key. if you dont get anything, you get the data from database and then save it into memcache. Which means you md5 the sql Query to make they key so it will be unique, and you pass the returned result from database as its value
key ===> md5(Sql Query )
value ==> the object, result set that is fetched from database
// pseudocode
if ( Get data from memcache passed )
{
return result;
}
else
{
get the data from database
save it into memcache
}
Note: If you are running on a single server, better to look into APC rather than memcached
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have a database on MySQL and I want to display one of my SQL tables on a HTML or PHP table. I have searched online and cannot implement this feature. Could someone please help me with the coding?
database = 'hrmwaitrose'
username = 'root'
host = 'localhost'
There is no password.
I would like to display the data from the "employee" table.
PHP provides functions for connecting to a MySQL database.
$connection = mysql_connect('localhost', 'root', ''); //The Blank string is the password
mysql_select_db('hrmwaitrose');
$query = "SELECT * FROM employee"; //You don't need a ; like you do in SQL
$result = mysql_query($query);
echo "<table>"; // start a table tag in the HTML
while($row = mysql_fetch_array($result)){ //Creates a loop to loop through results
echo "<tr><td>" . htmlspecialchars($row['name']) . "</td><td>" . htmlspecialchars($row['age']) . "</td></tr>"; //$row['index'] the index here is a field name
}
echo "</table>"; //Close the table in HTML
mysql_close(); //Make sure to close out the database connection
In the while loop (which runs every time we encounter a result row), we echo which creates a new table row. I also add a to contain the fields.
This is a very basic template. You see the other answers using mysqli_connect instead of mysql_connect. mysqli stands for mysql improved. It offers a better range of features. You notice it is also a little bit more complex. It depends on what you need.
Please note that "mysql_fetch_array" is now deprecated since PHP 5.5.0, and it was removed in PHP 7.0.0. So please take a look in "mysqli_fetch_array()" instead.
Here's a simple function I wrote to display tabular data without having to input each column name:
(Also, be aware: Nested looping)
function display_data($data) {
$output = '<table>';
foreach($data as $key => $var) {
$output .= '<tr>';
foreach($var as $k => $v) {
if ($key === 0) {
$output .= '<td><strong>' . $k . '</strong></td>';
} else {
$output .= '<td>' . $v . '</td>';
}
}
$output .= '</tr>';
}
$output .= '</table>';
echo $output;
}
UPDATED FUNCTION BELOW
Hi Jack,
your function design is fine, but this function always misses the first dataset in the array. I tested that.
Your function is so fine, that many people will use it, but they will always miss the first dataset. That is why I wrote this amendment.
The missing dataset results from the condition if key === 0. If key = 0 only the columnheaders are written, but not the data which contains $key 0 too. So there is always missing the first dataset of the array.
You can avoid that by moving the if condition above the second foreach loop like this:
function display_data($data) {
$output = "<table>";
foreach($data as $key => $var) {
//$output .= '<tr>';
if($key===0) {
$output .= '<tr>';
foreach($var as $col => $val) {
$output .= "<td>" . $col . '</td>';
}
$output .= '</tr>';
foreach($var as $col => $val) {
$output .= '<td>' . $val . '</td>';
}
$output .= '</tr>';
}
else {
$output .= '<tr>';
foreach($var as $col => $val) {
$output .= '<td>' . $val . '</td>';
}
$output .= '</tr>';
}
}
$output .= '</table>';
echo $output;
}
Best regards and thanks - Axel Arnold Bangert - Herzogenrath 2016
and another update that removes redundant code blocks that hurt maintainability of the code.
function display_data($data) {
$output = '<table>';
foreach($data as $key => $var) {
$output .= '<tr>';
foreach($var as $k => $v) {
if ($key === 0) {
$output .= '<td><strong>' . $k . '</strong></td>';
} else {
$output .= '<td>' . $v . '</td>';
}
}
$output .= '</tr>';
}
$output .= '</table>';
echo $output;
}
refer to http://www.w3schools.com/php/php_mysql_select.asp .
If you are a beginner and want to learn, w3schools is a good place.
<?php
$con=mysqli_connect("localhost","root","YOUR_PHPMYADMIN_PASSWORD","hrmwaitrose");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM employee");
while($row = mysqli_fetch_array($result))
{
echo $row['FirstName'] . " " . $row['LastName']; //these are the fields that you have stored in your database table employee
echo "<br />";
}
mysqli_close($con);
?>
You can similarly echo it inside your table
<?php
echo "<table>";
while($row = mysqli_fetch_array($result))
{
echo "<tr><td>" . $row['FirstName'] . "</td><td> " . $row['LastName'] . "</td></tr>"; //these are the fields that you have stored in your database table employee
}
echo "</table>";
mysqli_close($con);
?>
Look in the manual http://www.php.net/manual/en/mysqli.query.php
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
/* Create table doesn't return a resultset */
if ($mysqli->query("CREATE TEMPORARY TABLE myCity LIKE City") === TRUE) {
printf("Table myCity successfully created.\n");
}
/* Select queries return a resultset */
if ($result = $mysqli->query("SELECT Name FROM City LIMIT 10")) {
printf("Select returned %d rows.\n", $result->num_rows);
/* free result set */
$result->close();
}
/* If we have to retrieve large amount of data we use MYSQLI_USE_RESULT */
if ($result = $mysqli->query("SELECT * FROM City", MYSQLI_USE_RESULT)) {
/* Note, that we can't execute any functions which interact with the
server until result set was closed. All calls will return an
'out of sync' error */
if (!$mysqli->query("SET #a:='this will not work'")) {
printf("Error: %s\n", $mysqli->error);
}
$result->close();
}
$mysqli->close();
?>