can we simplify "while" inside of "while"? - php

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>";

Related

one PHP function to handle different MySQLi select statements

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.

How can I access query results in php where I'm returning values AS things? (Rather than looking at fields)

Apologies, I can't think of how to phrase this better (which has the additional problem of making it more difficult to research an answer, too). Suggestions for editing terms for clarity are more than welcome.
I am running two queries on a table in my database. The first simply returns all results within certain constraints imposed by the user - I'm echoing this out to a table with no problems at all. The second returns a COUNT and a SUM AS things, which I am having trouble accessing and echoing to the screen.
First Query -
$results = $connection->query(" SELECT `Date`, `Test`, `Errors` ... ");
while($result = $results->fetch_assoc())
{
echo "<tr>";
echo "<td>" . $result['Date'] . "</td>";
echo "<td>" . $result['Test'] . "</td>";
echo "<td>" . $result['Errors'] . "</td>";
echo "</tr>";
}
This works perfectly well. As expected, it echos out a table with the results in each row.
Second Query -
$totals = $connection-query("SELECT COUNT(*) AS Tests, SUM(`Errors`) AS TotalErrors ... ");
echo "<th>Total Tests</th>";
echo "<td>" . $totals['Tests'] . "</td>";
echo "<th>Total Errors</th>";
echo "<td>" . $totals['TotalErrors'] . "</td>";
I cannot seem to access the values in the second query to echo them to the screen.
I have tried using var_dump to ensure the query is returning results correctly, and it is. If I use var_dump($totals->fetch_assoc()); it will display array(2) { ["Tests"]=> string(2) "33" ["TotalErrors"]=> string(1) "9" }, as expected.
I'm not sure where I'm going wrong, looking at my syntax, it seems the same as when I access the values from the first query, but I'm not sure if it should be different because I am returning values AS rather than looking at field names.
Try
$results = $connection->query("SELECT COUNT(*) AS Tests, SUM(`Errors`) AS TotalErrors ... ");
$totals = $results->fetch_assoc();
echo "<th>Total Tests</th>;
echo "<td>" . $totals['Tests'] . "</td>";
echo "<th>Total Errors</th>";
echo "<td>" . $totals['TotalErrors'] . "</td>";

foreach loop from mysql query

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.

Integrating a INNER JOIN into an existing PHP function (PHP/MySQL)

I have an inner join working when used in SQL, however when I try to integrete it into a function in my PHP it gives me a syntax error of "unexpected '' (T_ENCAPSED_AND_WHITESPACE), expecting identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING)". The code is as follows:
echo "<table border=='1'>
<tr>
<th>Name</th>
<th>Exam Date</th>
<th>Level</th>
<th>Mark</th>
<th>Style</th>
</tr>";
while($row = mysql_fetch_array($exam_recordation))
{
echo "<tr>";
$name_query = mysql_query("SELECT DISTINCT student.name
FROM student
INNER JOIN exam ON student.email = exam.Student_email
WHERE student.email <> $row['Student_email']");
while($row = mysql_fetch_array($name_query))
{
echo "<td>" . $row['name'] . "</td>";
}
echo "<td>" . $row['examDate'] . "</td>";
echo "<td>" . $row['level'] . "</td>";
echo "<td>" . $row['mark'] . "</td>";
echo "<td>" . $row['style'] . "</td>";
echo "</tr>";
}
echo "</table>";
The reason I have the inner join there is because it requires Student_email from out of $exam_recordation for each record that it goes through. $exam recordation holds all records from the exam table that met the set conditions. I've seen from my own research that nesting queries is not the best thing to do, I don't think I am nesting queries but I am nesting while loops which to me looks to be suspiciously dangerous/bad practice. Its the only way I know how to perform this sort of function/operation.
The help I need is in working out how to get that inner join into that function. The inner join takes the name out of the student table for each email of each record that the first while loop goes through and echo's it in.
Basic PHP syntax: array keys in a double-quoted string can NOT be themselves quoted. e.g.
$arr = "This is an $array['reference']."
^-- ^-- incorrect
It should be either:
$arr = "This is an {$array['reference']}."; // note the {} notation
or
$arr = "This is an $array[reference]."; // Note lack of quotes.
Before I start, please note that mysql_ has officially become deprecated. You should move on to mysqli or pdo.
You might be closing your while loop before you originally intended... see below comments
while($row = mysql_fetch_array($name_query))
{
echo "<td>" . $row['name'] . "</td>";
} << REMOVE THIS
echo "<td>" . $row['examDate'] . "</td>"; << PHP NO LONGER KNOWS ABOUT $row
echo "<td>" . $row['level'] . "</td>";
echo "<td>" . $row['mark'] . "</td>";
echo "<td>" . $row['style'] . "</td>";
echo "</tr>";
}
You might also want to ensure that PHP is able to replace your query variable. MySQL will also need to see quotes around a string of text to make the comparison.. Try changing concatenating your query to...
$name_query = mysql_query("SELECT DISTINCT student.name
FROM student
INNER JOIN exam ON student.email = exam.Student_email
WHERE student.email <> '{$row['Student_email']}'");

Store and display MySQL result to/from PHP array

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.

Categories