Formatting MySQL Search Results - php

I’m currently working on a web site database. The entire site is coded in PHP (procedural style and not object oriented), of course with the obligatory CSS/HTML, etc.
I have everything working properly, but I am having trouble figuring out how to format search results the way I’d like.
Right now, I am displaying my search results in table format, with each cell of the table displaying a different variable from the search. All these little tables display vertically in one column, one after the other, until the end of the results.
What I am trying to do is display two columns of search results, side by side, to fit more results on the screen at one time. I have been able to display two columns of duplicate results, but I’d like two columns of alternating, non-duplicate results.
The current layout of my results is something like:
Result 1
Result 2
Result 3
Result 4
What I have been able to accomplish in my attempts:
Result 1 Result 1
Result 2 Result 2
Result 3 Result 3
Result 4 Result 4
What I would like to have:
Result 1 Result 2
Result 3 Result 4
Result 5 Result 6
Result 7 Result 8
Can anyone shed some light on how to achieve this? I’m not sure if it's a simple CSS/HTML formatting solution, or a PHP/MySQL solution.
Below is the code that specifically relates to the loop that displays my results:
$link = mysqli_connect( ALL MY INFO );
include('strings.php'); //This script sets the SQL search string based on user input.
echo '<br />';
$query = mysqli_query($link, $string) or die ("Error retrieving search results. Error in (main.php) search function.");
$resultrows = mysqli_num_rows($query);
echo '<table>
<tr>
<td colspan=2>
<h3>Showing '.$resultrows.' results. </h3>
</td>
</tr>
<tr>
<td>';
while ($result = mysqli_fetch_assoc($query)){
include('results.php'); //This script formats each search result
}
echo ' </td>
<td>';
$query = mysqli_query($link, $string) or die ("Error retrieving search results. Error in (main.php) search function.");
while ($result = mysqli_fetch_assoc($query)){
include('results.php');
}
echo ' </td>
</tr>
</table>';

I believe the magical solution to your problem would be to use the modulus (remainder) operator in PHP:
Remainder of $a divided by $b.
Might be an odd concept to understand if you’re not into math—and programming is all about logic really—but once you get what a modulus (remainder) operator can do, it is a magical thing.
Basically calculate a modulus based on a counter within a loop. And then at that point the remainder of the modulus value would be 0… Et voilà! You can do something! The examples below use tables and rows, but the same, basic concept could be used for other HTML elements or any formatting logic.
For example, let’s take this simple PHP code to create a table based on a simple alphabet array:
$array = range('a','z');
echo '<table border="1">';
echo '<tr>';
foreach ($array as $key => $value) {
echo '<td>';
echo $value;
echo '</td>';
}
echo '</tr>';
echo '</table>';
The output would be one table with one large ugly row that renders like this:
a b c d e f g h i j k l m n o p q r s t u v w x y z
But if we add some modulus logic to the mix like this:
$row_cell_amount = 2;
$array = range('a','z');
echo '<table border="1">';
echo '<tr>';
$counter = 1;
foreach ($array as $key => $value) {
echo '<td>';
echo $value;
echo '</td>';
if ($counter % $row_cell_amount == 0 && $counter != 0) {
echo '</tr>';
echo '<tr>';
}
$counter++;
}
echo '</tr>';
echo '</table>';
The output will cleanly add a new row every time the $counter value evenly matches the modulus operator resulting in 0; aka: no remainder. So the output would look like this with a value of 2 for the $row_cell_amount:
a b
c d
e f
g h
i j
k l
m n
o p
q r
s t
u v
w x
y z
And if you adjusted the $row_cell_amount to be something like 4, the output would be something like this:
a b c d
e f g h
i j k l
m n o p
q r s t
u v w x
y z
Small note but in this simple example you can perhaps set $key+1 instead of creating a $counter but just showing the $counter method since you might be dealing with associative arrays that are non-numerical or non-numerically ordered as far as key values go.

Related

Generating rows and columns within a given range of numbers - PHP

I'm trying to build a little program to automatize a little task; in it, one can write two values (as inputs in a form) and then, in another page, numbers will be written in rows and columns with all the numbers within the range given.
The thing is... There will (almost always) be 500 numbers in the range, so I want the result to be displayed in 10 columns of 50 rows each, something like this image:
I wanted the result page (the one with all the numbers) to THEN give the possibility to export this as xml or pdf, but that's another story..
By now, I just would like to get the display right.
I'm using HTML and PHP on XAMPP. I've been able to get the first column... but can't get to the generations of the others, like this (and so on until 50):
So far, this is what I have, I'll put here my PHP code, because I don't think the HTML is relevant (but will post it too if it's needed) - (The values are passed by POST method)
<?php
$cont = 0;
$i = 0;
$arrayValues = range($valueFrom, $valueTo);
if($cont <= 50){
echo "<tr>";
for($i = 0; $i < 50; $i++){
echo "<p>$arrayValues[$i]</p>";
$cont++;
}
echo "</tr>";
}
?>
Also, using something like this --> Use PHP to Generate HTML table with static Cell Count of MySQL Data and worked ok, but I would the numbers displayed in columns... so not in rows (horizontally), so..
YES | NO
1 4 7 | 1 2 3
2 5 8 | 4 5 6
3 6 9 | 7 8 9
That's why I stopped trying with tables and just used a tag for the result.
EDIT:
So, given the "start" value and "end" value for a range, I would like to be able to print all those values in 10 columns of 50 rows each (so when it reaches 50 rows in the first column, it automatically moves to a new column and so on), and vertically (like the little diagram I tried to put above this, in the "YES" side)
Any ideas or guidance will be appreciated! :)
Have a nice rest of the week!
You can do this by splitting your range up into chunks and indexing into the resulting array of columns in a nested loop.
<table>
<?php
$valueFrom = 1;
$valueTo = 500;
$rowCount = 50;
$columns = array_chunk(range($valueFrom, $valueTo), $rowCount);
$columnCount = count($columns);
for ($row = 0; $row < $rowCount; $row++) {
echo '<tr>';
for ($column = 0; $column < $columnCount; $column++) {
$number = $columns[$column][$row] ?? '';
echo "<td>$number</td>";
}
echo '</tr>';
}
?>
</table>

Reordering a sql matrix on php

This is more of a php question than a sql one.
I have a database like this:
A B C D E
1 1
1 1 1
1 1
I need to order it but not using ORDER BY becouse the parameter needed is not inside the table. I need a sum of several of this numbers "1".
If my requirements needs the fields A, B, C. So the result of the second row is 3, the first row is 2 and the third one is 1.
But if my requirements change for example to just include the field E, then the third row has "1" and the other just have 0.
So I need to sume theese values, something like this:
while($row = $result->fetch_assoc()) {
$ranking = $row['A'] + $row['B'] + $row['C'] + $row['D']
;}
I think I need to now insert this new $ranking value inside the $result matrix, and then, sort it using that column and brake it again... But that goes beyond my comprehension of php?
Any light on this please?
Edited 1:
Can I do something like this?
while($row = $result->fetch_assoc()) {
$result = array("$row['A']" => ($row['A'] + $row['B'] + $row['C'] + $row['D']))
;}
Consider a simple select query and have PHP dynamically build the sum string if selected columns regularly change. Use the calculated column for your other application needs.
SQL (sqlfiddle)
SELECT IFNULL(`A`, 0) + IFNULL(`B`, 0) + IFNULL(`C`,0) As ColsSum
FROM matrix;
PHP
$cols = array('A', 'B', 'C', 'D', 'E');
$selected = array('A', 'B', 'C');
$colsSQL = "";
$results = array_intersect($cols, $selected);
foreach ($results as $a) {
$colsSQL .= 'IFNULL(`'. $a .'`,0) + ';
}
$colsSQL = substr($colsSQL, 0, -2);
$strSQL = "SELECT ". $colsSQL ." As ColSums FROM matrix;";
...
mysqli_query($conn, $strSQL);

Pagination of PHP echoed Content

PHP is an alien language for me. I am trying to pull some fields from WP's SQL database.. The content comes out okay but is a lot. I want to somehow put it in a HTML carousel or some slider, where data must be formatted like this:
<holder1>
<data1></data1>
<data2></data2>
<data3></data3>
</holder1>
<holder2>
<data4></data4>
<data5></data5>
<data6></data6>
</holder2>
I imagine I would have to put some for loop for i<4, do, then break into holder2.
Current script that echos the data =
while($row = mysql_fetch_array($rs)) {
echo "<div class='testimonials flexslider'><ul class='slides'><li class='testimonial flex-active-slide'><blockquote><p>" . $row['post_content'] . "</p><cite><span>" . $row['post_title'] . "</cite></span></blockquote></li></ul></div>"; }
I would like it to break after 3 <li> items each, into a seperate <div> or <article> whatever I find suitable according to the carousel I use.
You need an index variable, which echoes the beginning of the wrapper when it is divisible by 3, and the end of the wrapper when it leaves a remainder of 2 after division by 3 (and at the very end). It seems like this code would work:
$index = 0;
while($row = mysql_fetch_array($rs)) {
if ($index % 3 == 0) {
echo "<div class='testimonials flexslider'><ul class='slides'>";
}
echo "<li class='testimonial flex-active-slide'><blockquote><p>" . $row['post_content'] . "</p><cite><span>" . $row['post_title'] . "</cite></span></blockquote></li>";
if ($index % 3 == 2) {
echo "</ul></div>";
}
$index++;
}
if ($index % 3 != 2) {
echo "</ul></div>";
}
EDIT: a little bit of explanation to clarify the math. Suppose you have 10 results. Because we usually count from 0 in programming, they can be numbered 0 up to 9. This would make your structure look like this:
<holder>
<data0></data0>
<data1></data1>
<data2></data2>
</holder>
<holder>
<data3></data3>
<data4></data4>
<data5></data5>
</holder>
<holder>
<data6></data6>
<data7></data7>
<data8></data8>
</holder>
<holder>
<data9></data9>
</holder>
You see that we need a <holder> before elements 0, 3, 6 and 9 - all numbers which are divisible by 3. Mathematically, this is expressed with help of the remainder function - a number is divisible by 3 when its remainder after dividing by 3 is zero.
Likewise, we need a </holder> after elements 2, 5 and 8 - numbers which after division by 3 leave a remainder of 2.
We need to take care of the situation where the last block is not complete; that's why there's an extra block of code to take care of the last </holder>.

Using Median Function with sort and Array

I am trying to calculate the Median of an array. I was able to get the MIN, MAX, AVG, But I am having difficulty with the Median and the way the display sorts the information.
My Question is How do I get the Median, using a function individually for each status. (Status being A, C, E, L, P, W)
My Code is:
<?php
echo "<p><b>A</b> = Active, <b>E</b> = Expired, <b>L</b> = Canceled, <b>P</b> = Pending, <b>W</b> = Withdrawn</p>\n";
// COUNT STATUS
include '_inc/include.php';
$query = "SELECT status, COUNT(status) FROM median GROUP BY status";
$result = mysql_query($query) or die(mysql_error());
// Print out result
while($row = mysql_fetch_array($result)){
echo "There are ". $row['COUNT(status)'] ." ". $row['status'] ." items.";
echo "<br />";
}
?>
The display is:
A = Active, C = Closed, E = Expired, L = Canceled, P = Pending, W = Withdrawn
There are 6 A items
There are 2 C items
There are 9 E items
There are 4 L items
There are 2 P items
My Code is:
$query = "SELECT listprice, status, MIN(listprice), COUNT(status) FROM median GROUP BY status";
$result = mysql_query($query) or die(mysql_error());
// Print out result
while($row = mysql_fetch_array($result)){
echo "The MIN list price for the ". $row['COUNT(status)'] ." ". $row['status'] ." is $" . $row['MIN(listprice)'];
echo "<br />";
}
?>
The display is:
The MIN list price for the 6 A is $139900.00
The MIN list price for the 2 C is $149900.00
The MIN list price for the 9 E is $138000.00
The MIN list price for the 4 L is $229000.00
The MIN list price for the 2 P is $179000.00
The MAX and AVG is similar to the above.
I tried to include a function to calculate the Median (MED)
<?php
function median($arr)
{
sort($arr);
$count = count($arr); //count the number of values in array
$middleval = floor(($count-1)/2); // find the middle value, or the lowest middle value
if ($count % 2) { // odd number, middle is the median
$median = $arr[$middleval];
} else { // even number, calculate avg of 2 medians
$low = $arr[$middleval];
$high = $arr[$middleval+1];
$median = (($low+$high)/2);
}
return $median;
}
echo median(array($lp)) . "\n"; // 153500
echo "<p> </p>";
echo median(array(4.1, 7.2, 1.7, 9.3, 4.4, 3.2)) . "\n"; // 4.25
?>
This works for a static array, but how do I calculate it to look like the above MIN, MAX?
<?php
$i=0;
while ($i < $num) {
$ld=mysql_result($result,$i,"listdate");
$cd=mysql_result($result,$i,"closedate");
$contractd=mysql_result($result,$i,"contractdate");
$s=mysql_result($result,$i,"status");
$scd=mysql_result($result,$i,"statuschangedate");
$wd=mysql_result($result,$i,"withdrawdate");
$cand=mysql_result($result,$i,"canceldate");
$lp=mysql_result($result,$i, "listprice");
$sp=mysql_result($result,$i,"soldprice");
$gla=mysql_result($result,$i,"gla");
$b=mysql_result($result,$i,"built");
$o=mysql_result($result,$i,"owner");
$fs=mysql_result($result,$i,"fore");
$ss=mysql_result($result,$i,"shortsale");
$f=mysql_result($result,$i,"features");
?>
I think maybe the reason I having so much trouble with this is that the data in the table is uploaded via file upload (csv). But I didn't think that really had anything to do with it because the data is already there.
I used $lp for listprice in place of the static array in the median function, that is were it goes blank.
...that is where it goes blank.
Blank pages are an indicator of an PHP error being thrown but having error display settings turned off. Make sure you turn on error reporting to see the issue.
One thing of importance, the deprecated mysql_result() function will retrieve the contents of one cell from a MySQL result set. If you were hoping to have multiple values by passing your median function array($lp) it's not going to happen that way. Additionally, if the mysql_result() function fails or doesn't find a result, it returns false mean the array you pass to your median function is now array(false).
Those are some things to keep in mind while troubleshooting. Turn on error reporting and the problem should be much easier to deduce.
There is no median function for most MySQL versions. However, MariaDB 10.3.3 just introduced a median function.

Issue with coordinating a table with dynamic rows and columns

Bear with me here--this may be a bit confusing.
I am retrieving two sets of data with SQL. Here's the code, with the query. I'm using Zend Framework.
$assignments = $db->fetchAll("SELECT id,name,class FROM assignments");
foreach($assignments as $a) {
$assignmentID = $a['id'];
$studentData = $db->fetchAll(
"SELECT student,assignment,status,assignmentID FROM student_assignments WHERE assignmentID='$assignmentID'"
);
echo "<th>".$a['name']."</th>";
foreach($studentData as $s) {
$bottom .= "<tr><td>" . $s['student'] . " " . $s['assignmentID']
. " ".$s['status'] . "</td></tr>";
$i++;
}
}
echo "</tr>$bottom;";
Here's what the output looks like in the HTML:
|Assignment on 07/07/2012| |Assignment on 07/12/2012| |Assignment on 07/15/2012|
117 1 Y
332 1 N
36 1 N
420 1 N
332 1 Y
326 2 N
212 2 N
461 2 N
117 2 N
212 2 N
212 3 N
326 3 N
117 3 Y
420 3 Y
Now the top part is working great -- it's dynamically showing each assignment in the database. But I've been trying to figure out a way to get the appropriate data to show under those columns, to no effect. This is the closest I've gotten to making it look somewhat correct.
Essentially, the data that has "2" and "3" in the middle should go into the 2nd and 3rd columns, respectively. But this isn't happening because all the data is stored into the $bottom variable, rather than the data for each assignment.
Does anyone have any suggestions? This is driving me crazy, and I feel like the solution is staring me in the face.
Thanks!
First you want to iterate through every of your student assignments, and left join the assignments table to it so you can know the name of the assignment that it is related to.
$students = $db->fetchAll('SELECT sa.student,sa.assignment,sa.status,sa.assignmentID,a.name
FROM student_assignments AS sa
LEFT JOIN assignments AS a ON sa.assignmentID=a.id');
Then with the results, you can build an array to regroup everyone with the same assignment:
$columns = Array();
foreach($students as $s) {
$row = '<tr><td>'.$s['student'].' '.$s['assignmentID'].' '.$s['status'].'</td></tr>';
array_push($columns[$s['name']], $row);
}
Then with this array, you can finally print your content:
foreach ($columns as $key=>$value) {
echo '<th>'.$key.'</th>';
foreach ($value as $v) {
echo $v;
}
}
Of course this can be more compact (reduced into nested loops), and I have no way to fully test it, but it should help you in your process ;)

Categories