I have working code but I seem to have introduced a bad bottleneck to my code. Before I go into detail, let me give you some background on what this code does. I have a table generated in PHP/HTML that shows a list of parts that are in a database (149 parts). The user can select a quantity for that item and click "Add To Cart" which all works fine.
However, I tried to spruce things up a bit by adding in a feature that only allows the user to select the quantity we actually have on hand for this product (before add this feature I previously had the max value hard coded at 100).
Now this does work, but it is TERRIBLY slow (50 seconds to load the page). However, before implementing this the page loaded immediately without a problem, therefore this is definitely a problem with the getPartQuantityOnHand() function.
I think the problem is that for every part (149) I am calling this function that then has to reconnect to the database to find the correct quantity. Does anyone see a way I can improve this? FYI, the parts are hosted on a completely separate database from where the quantity on hand for these parts are hosted.
I have left some parts out of the php code since it was unnecessary bulk for this post, I know that I am missing parts here.
getParts.php
<?php
$partList = $_SESSION['controller']->getParts();
foreach ($partList as $part) {
//Call to get the current quantity on hand for this specific part
//THIS IS WHEN THE PROBLEM WAS INTRODUCED
$quantityOnHand = $_SESSION['controller']->getPartQuantityOnHand($part->number);
//Only display this part if we have at least one on hand
if ($quantityOnHand > 0)
{
echo "<tr>";
echo "<td>" . $part->number . "</td>";
echo "<td>" . $part->description . "</td>";
echo "<td>$" . $part->price . "</td>";
echo "<td>";
echo '<input name="qty'. $part->number .'" type="number" value="1" min="1" max="' . $quantityOnHand .'"/>';
echo "</td>";
echo "</form>";
echo "</td>";
echo "</tr>";
}
}
echo "</table>";
echo "</div>";
?>
getPartQuantityOnHand()
public function getPartQuantityOnHand($partNum) {
$conn = $this->connect();
$sql = "select Quantity from ReceivingInfo where PartNumber = '$partNum'";
$stmt = $conn->prepare($sql);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$quantityOnHand = $row['Quantity'];
return $quantityOnHand;
}
Thanks for any help you can provide!
As the two databases are separate you have two options:
Determine the part numbers before you loop and generate your HTML, then query all at the same time with an IN clause:
SELECT ... WHERE PartNumber IN (1, 2, 3, 4);
Select all stock levels for your parts when you first call getPartQuantityOnHand and store that:
public function getPartQuantityOnHand($partNum) {
if(!$this->partQuantitiesOnHand) {
$conn = $this->connect();
$sql = "select Quantity, PartNumber from ReceivingInfo";
$stmt = $conn->prepare($sql);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$this->partQuantitiesOnHand = array_column($rows, 'Quantity', 'PartNumber');
}
return $this->partQuantitiesOnHand[$partNum] ?? null;
}
The disadvantage of option 2 is that if you have many more parts than are listed on a single page, it will never perform as well as option 1.
So, instead of doing a 149 different SQL queries, just do one query that brings back all the Quantity values you need.
ex.
SELECT Quantity FROM ReceivingInfo WHERE PartNumber IN ($listOfPartNums)
of course you will have to build the string $listOfPartNums
Or, if you really are always bringing back the full list of them, you can exclude the IN clause and don't need to worry about generating the string.
You'll have to change your function a bit to store the partnum/quantity pairs in an associative array.
Then in your getParts.php get the Quantity like this:
<?php
$partList = $_SESSION['controller']->getParts();
$quantityList = getQtyList(); // return assoc array of partnum/qty pairs
foreach ($partList as $part) {
//Call to get the current quantity on hand for this specific part
//THIS IS WHEN THE PROBLEM WAS INTRODUCED
$quantityOnHand = $quantityList[$part->number];
//Only display this part if we have at least one on hand
if ($quantityOnHand > 0)
{
echo "<tr>";
echo "<td>" . $part->number . "</td>";
echo "<td>" . $part->description . "</td>";
echo "<td>$" . $part->price . "</td>";
echo "<td>";
echo '<input name="qty'. $part->number .'" type="number" value="1" min="1" max="' . $quantityOnHand .'"/>';
echo "</td>";
echo "</form>";
echo "</td>";
echo "</tr>";
}
}
echo "</table>";
echo "</div>";
?>
Related
i need some little help ,,,
I have a data like this.., (I use php mysql)
Initially there was no problem with this, but as time goes by, my data is getting bigger and bigger.
finally its made my program slow ..
I think maybe because I used "while" inside of "while". make SQL is called multiple times.
is there a solution to make it faster ??
I have hundreds of data in tb1 and thousands in tb2 T.T
You should not be using loops to iterate over tables. SQL is an inherently set based declarative language. So, you should just join the tables, order the result set, and then use a single loop with presentation logic. Use this query:
SELECT tb1.id_a, tb2.id_b, tb2.data
FROM tb1
INNER JOIN tb2 ON tb2.id_a = tb1.id_a
Then, use this PHP script:
echo "<table>";
echo "<tr><th>No.</th><th>id_b</th><th>data</th></tr>";
$a = null;
while ($row = mysql_fetch_array($result)) {
if ($a == null || $row['id_a'] != $a) {
echo "<tr>";
echo "<td>" . $row['id_a'] . "</td>";
echo "<td colspan=2>data" . $row['id_a'];
echo "</tr>";
$a = $row['id_a'];
}
echo "<tr>";
echo "<td></td>";
echo "<td>" . $row['id_b'] . "</td>";
echo "<td>" . $row['data'] . "</td>";
echo "</tr>";
}
echo "</table>";
I have two MySQL tables with number of columns. The table structure is given below,
1.pictures
postedON
caption
imageName
thumbName
imageLocation
thumbLocation
2.Videos
postedOn
category
Link
I am using the folowing PHP function to fetch data from DB using a select command.
function select($table){
if($this->db_connection){
$query = 'SELECT * FROM '. $table;
$result = mysqli_query($this->db_connection,$query) or die($this->db_connection->error);
//print_r($result);
//echo "Affected rows: " . mysqli_affected_rows($this->db_connection);
//var_dump($result);
echo "<table>";
echo "<tr>";
echo "<th>Date Posted</th>";
echo "<th>Category</th>";
echo "<th>Link</th>";
echo "</tr>";
while($row = $result->fetch_assoc()){
echo "<tr>";
echo "<td>" . $row['postedOn'] . "</td>";
echo "<td>".$row['category']. "</td>";
echo "<td>" . $row['link'] . "</td>";
echo "</tr>";
}
echo "</table>";
}else{
echo "db_connection is = " . $this->db_connection;
}
}
}
The problem with this function as you can see, it can only serve only one table and not dynamic. Can someone please explain the way to dynamically fetch data from different table with different number of columns using only one PHP function? Thanks
Try using mysqli_fetch_fields()
<?php
function select($table){
if($this->db_connection){
$query = 'SELECT * FROM '. $table;
$result = mysqli_query($this->db_connection,$query) or die($this->db_connection->error);
$fieldinfo = mysqli_fetch_fields($result);
echo "<table>";
echo "<tr>";
foreach ($fieldinfo as $val)
{
echo "<th>".$val->name."</th>";
}
echo "</tr>";
while($row = $result->fetch_assoc()){
echo "<tr>";
foreach ($fieldinfo as $val)
{
echo "<td>" . $row[$val->orgname] . "</td>";
}
echo "</tr>";
}
echo "</table>";
}else{
echo "db_connection is = " . $this->db_connection;
}
}
It could be hard to explain given all the wrong premises you approach is based on, but I'll try.
First of all, you have to understand that a query like SELECT * FROM table has a very little use, next to none. Most of time you are always have some WHERE or at least LIMIT clause. So, such a function will have no use at all.
Next, you have to learn by heart that database interaction should never be intermixed with any output stuff like HTML.
Given these two premises above, your function should accept a fill qualified query as a parameter and return an array with data as a result.
For which array, in turn you can write a helper function to display its contents in the form of HTML table.
But again, such a generalized output function will be of little use as well, because, as you can see from your own example, different fields will need different formatting. So it's better to write output each time by hand.
very new to php and mysql so all help is greatly appreciated. I have tried to search the forums but not entirely sure specifically what I need to be searching for. I have a form which ask users to select a product and make a comment.
I need the information for a particular product to show on my product page instead of all of the information. (for example, I want the reviews for iPads to show on the ipad page)
This is the code that send the data to the database:
<?php
session_start();
include('connection.php');
$name=$_POST['name'];
$product=$_POST['product'];
$star=$_POST['star'];
$comment=$_POST['comment'];
mysql_query("INSERT INTO tt_review(name, product, star, comment)VALUES('$name', '$product', '$star','$comment')");
header("location: https://scm-intranet.tees.ac.uk/users/l1071039/tablet-takeover/index.html");
mysql_close($con);
?>
This is the current code to fetch the data onto my page:
<?php
include('connection.php');
$result = mysql_query("SELECT * FROM tt_review");
echo "<table border='1'>
<tr>
</tr>";
while($row = mysql_fetch_array($result)) //This function is calling the results variable and displaying them within the rows below
{
echo "<tr>"; //this code tells the page to output the table rows that are defined above
echo "<td>" . $row['name'] . "</td>";
echo "<td>" . $row['date'] . "</td>"; //each row is then executed using the table data function
echo "<td>" . $row['product'] . "</td>";
echo "<td>" . $row['star'] . "</td>";
echo "<td>" . $row['comment'] . "</td>";
echo "</tr>";
}
echo "</table>";
?>
This is a screenshot of the table on my webpage (as I say, I need it to only show the ipad reviews.
To select only one kind of product, you should add a where clause on your sql query:
SELECT * FROM tt_review WHERE product = 'Apple iPad'
You can give like this
"SELECT * FROM tt_review WHERE Product_name ='ipad'"
It will display only the information related to Ipad
Still If you dont understand please give me the name of the columns you used in the table
Firstly, mysql_* functions have been depreciated. Rather, use either PDO or MySQLi.
Secondly, your code is very vulnerable to SQL injection.
Thirdly, fix your select statement to the following:
SELECT * FROM tt_review WHERE product = 'ipad'
Coming back to my project after putting it down for a while: Cycling through a query.
I understand that the below code can be cleaned up (PHP usage and table arrangement) and that MySQL commands are deprecated. ( I am working on that part).
But I can't see why I can't make this work. The print_r() gives Resource ID #5 error. My results show 2 tables, each with identical results all from the same course. I am expecting 8 tables, each table with a different course.
Should I use a while loop? if so how? I realize this is elementary, but this is still all new to me so please be gentle.
<?php
include 'inc.php';
$varVeh=$_POST['Veh_num'];
$sql_course="select course_num from hc_course";
$results_course=mysql_query($sql_course);
print_R($results_course);
foreach(mysql_fetch_array($results_course) as $rc)
{
$sql_HiScores = "SELECT c.course_name as course, e.distance as distance, e.score as score, e.time as time, e.user as User from hc_entries e left join hc_course c on e.course=c.course_num WHERE c.course_num=$rc and e.vehicle=$varVeh ORDER BY course, score DESC ";
$result_HiScores = mysql_query($sql_HiScores);
$sql_vehName="select Veh_name from hc_vehicle_type where Veh_num=$varVeh ";
$result_vehName = mysql_query($sql_vehName);
$vehName=mysql_fetch_assoc($result_vehName);
echo "<table><tr><th>Best Scores for ".$vehName['Veh_name']."</th> </tr></table>";
echo "<table border='1'>";
echo "<tr><th>Course</th><th>Score</th><th>Distance</th><th>Player</th><th>Time</th></tr>";
while($row = mysql_fetch_array($result_HiScores))
{
echo "<tr>";
echo "<td>" .$row['course'] . "</td>";
echo "<td>" .$row['score'] . "</td>";
echo "<td>" .$row['distance'] . "</td>";
echo "<td>" .$row['User'] . "</td>";
}
echo "</table>";
}
?>
mysql_fetch_array just returns one row of the results, not all the rows. Your foreach loop is just looping over the columns in the first row of results.
If you want to process all the results, you should write:
while ($rc = mysql_fetch_array($results_course))
Then inside your loop, you use $rc['course_num'] to get the course from that row.
But I don't understand why you need that first loop at all. You're JOINing the hc_courses and hc_entries tables in the first query inside the loop. Why don't you just use that same query, but without the c.course_num = $rc condition, so it gets all courses at once instead of doing them one course at a time? Loop over those results, and start a new table every time the course number changes.
Here's the query for that:
SELECT c.course_name as course,
e.distance as distance,
e.score as score,
e.time as time,
e.user as User,
c.course_num as course_num
FROM hc_entries e
JOIN hc_course c ON e.course=c.course_num
WHERE e.vehicle=$varVeh
ORDER BY course, score DESC
The PHP then looks like:
$last_course = null;
while ($row = mysql_fetch_assoc($results_HiScores) {
if ($row['course_num'] !== $last_course) {
// New course number, start a new table
if ($last_course !== null) {
// Close out last table, if any
echo '</table>';
}
$last_course = $row['course_num'];
echo "<table><tr><th>Best Scores for ".$vehName['Veh_name']."</th> </tr></table>";
echo "<table border='1'>";
echo "<tr><th>Course</th><th>Score</th><th>Distance</th><th>Player</th><th>Time</th></tr>";
}
echo "<tr>";
echo "<td>" .$row['course'] . "</td>";
echo "<td>" .$row['score'] . "</td>";
echo "<td>" .$row['distance'] . "</td>";
echo "<td>" .$row['User'] . "</td>";
echo "</tr>";
}
if ($last_course !== null) {
echo "</table>";
}
And you shouldn't do the hc_vehicle_type query inside the loop. It doesn't use any variables that change during the loop, it's just looking up the name of $_POST['Veh_num']. Just do it once and reuse the result inside the loop.
try:
foreach(mysql_fetch_array($results_course, MYSQL_ASSOC) as $rc)
{
....
}
if second argument is not given, MYSQL_BOTH is assumed, so array has column name, and column number 0,1...,n . so you traversed result set twice (column name and column number)
RTMF : http://us1.php.net/manual/en/function.mysql-fetch-array.php
and The print_r() gives Resource ID #5 error this is not an error!. return value of mysql_query() is result set. it's just a Resource of PHP internal structure.
Suppose I have the following MySQL table result:
ID price
-------------
1 10
2 20
3 30
Basically what I want to accomplish is to store these values to a PHP array, and have these values displayed/echoed as a HTML table on a per row basis.
I could do something like:
if($result) {
$i = 0;
while ($row = mysql_fetch_array($result)) {
$id[$i] = $row['id'];
$price[$i] = $row['price'];
}
}
And just have those elements echo together with the HTML table.
However, I also need to have a function that allows the user to delete a row. With that mind I believe I need to have some sort of a 'key' for every row as the identifier for deletion -- a feature which multidimensional array supports.
There's nothing preventing you from using a multi dimensional array and using one of the unique values as an index:
// Store result
$data = array();
if($result) {
while ($row = mysql_fetch_array($result)) {
$data[$row['raiser_id']] = $row;
}
}
// Building table
echo "<table>";
foreach ($data as $row)
{
echo "<tr>";
echo "<td>" . $row['raiser_id'] . "</td>";
echo "<td>" . $row['name'] . "</td>";
echo "<td>" . $row['fcr'] . "</td>";
echo "<td>" . $row['date_of_application'] . "</td>";
echo "<td>" . $row['no_of_heads'] . "</td>";
echo "<td>" . $row['place_of_farm'] . "</td>";
echo "</tr>";
}
echo "</table>";
// Removing an entry by raiser_id
$raiser_id = 10;
if (!empty($data[$raiser_id]))
{
unset($data[$raiser_id]);
echo "Removed entry";
}
else
{
echo "No entry to remove";
}
To delete a row from the database, you have to have another PHP script and have to call it using POST method and run an SQL query in it.
If you are talking of just displaying this table, PHP has nothing to do here then - go for JavaScript.
By the time a user sees his table, there is no mysql result, no PHP array and no whole PHP running either. It's all dead long time ago. Keep that in mind.