How to split SQL query results into chunks in PHP - php

I am trying to break query results into chunks using PHP but can't seem to figure out how to formulate either a query or a loop to break the results into batches of four and surround those four rows with specific HTML elements.
The content is specifically a photography portfolio, where I am just attempting to display photos row by row, but the way I need to style it calls for each row to basically be a separate set of information.
This is the code I'm working with thus far:
<ul class="no-bullet">
<?php
require("connect.php");
$query = "SELECT * FROM dv_photo_work LIMIT 4";
$result = mysql_query($query, $link);
while ($row = mysql_fetch_array($result)) {
print('
<li><img alt="'.$row["img_title"].'" src="'.$row["img_slug"].'></li>');
}
?>
</ul>
I only want four images to be in that list though. And then another four in another list. Can you help me reformulate the loop to make it return four records and then begin a new query of the following four records in another list? There will be approximately 100 records in the database that I will be retrieving this from, so it would have to be able to continue until the entire table is listed.
I imagine this is similar to a pagination process, yet that is another technique that I am unfamiliar with. I'm assuming it's a simple adjustment to the query and mark-up, however I could understand it being something that requires a bit more code creativity than a simple fix.
Many thanks,
Joshie

Try this
<ul class="no-bullet">
<?php
require("connect.php");
$query = "SELECT * FROM dv_photo_work";
$result = mysql_query($query, $link);
$i =1;
while($row = mysql_fetch_array($result)) {
print('<li><img alt="'.$row["img_title"].'" src="'.$row["img_slug"].'></li>');
if ($i%4 == 0) echo "</ul><ul class='no-bullet'>";
$i++;
}
?>
</ul>

First! move that logic far away from the html, that will allow you to see the problem more clearly. Second! what about two classes a Class A that represents an n-length list of query results. Class A should be an iterator, so that a Class B can pull arbitrary length chunks of results and return appropriately sized result objects. maybe there's a third class whose instances represent the sized constrained result. So all in all three classes A representing a full list of results, B acting on a and returning instances of C which would represent your sized constrained result chunks.
This was originally a comment, but it was too long, so I had to make it an answer (sorry if it's too 'teach a man to fish' I just don't want to write php...)

Get all your results, read them into a multidimensional array, and then split them into groups with array_chunk().
$query = mysql_query("SELECT * FROM dv_photo_work",$link);
$results = array();
while($line = mysql_fetch_array($query, MYSQL_ASSOC)){
$results[] = $line;
}
$lists = array_chunk($results,4);
foreach ($lists as $list) {
echo '<ul>';
foreach ($list as $result) {
echo '<li><img alt="'.$result["img_title"].'" src="'.$result["img_slug"].'></li>'
}
echo '</ul>';
}

Here is an outline of the logic involved, using the modulus operator (%) to change the HTML at every fourth record:
$i = 0;
// within your current while-loop:
if ($i % 4 == 0) {
// $i is a multiple of 4 (including 0, the first record)
if ($i > 0) {
// finish the previous ul-tag
}
// start a new block of HTML (the ul)
}
// output the li
$i += 1;
// after the loop, close the last ul

Related

making combinations of data in while loop

I have two tables. First one contains first names, second one contains last names. (I could do it with one table with two columnes, but I'm using this way for other reason)
I want to make all possible combinations.
So if there are first names: John, Zed, Marko, and last names: Abbot, Zang I would like to get output like:
JohnAbbot
JohnZagn
ZedAbbot
ZedZang
MarkoAbbot
MarkoZang
I did something similar with For loop and alfanumeric signs. I was able to do it with 6 nested for loops, but I can't get this to work with while loop.
this is the code I use:
$query_name = "SELECT name FROM names";
$results=mysqli_query($connect, $query_name);
$query_surname = "SELECT surname FROM surnames";
$results2=mysqli_query($connect, $query_surname);
while ($row = mysqli_fetch_assoc($results)) {
while ($row2 = mysqli_fetch_assoc($results2)) {
echo $row['name'].$row2['surname']."<br/>";
}
}
with this I got only combinations with 1 name and all surnames.
after I added one more echo in first while loop like this:
while ($row = mysqli_fetch_assoc($results)) {
echo $row['name']."<br/>";
while ($row2 = mysqli_fetch_assoc($results2)) {
echo $row['name'].$row2['surname']."<br/>";
}
}
with this I got:
first name from names table
combinations with first name and all last names (surnames)
all others names
I did not get all the combinations with all names and surnames.
What am I doing wrong?
Thank you in advance
(sorry for my bad english)
That's because fetching is only done once per handle, so when your inner loop reaches the end of records, it will never go back to the first one - as you would need it to - but stay at the end and return false.
If your result sets are not million-row ones, try fetching both only once, then combine the arrays and foreach-loops which will obediently start from the beginning each time:
$a1 = array();while ($row = mysqli_fetch_assoc($results)) $a1[]=$row;
$a2 = array();while ($row = mysqli_fetch_assoc($results)) $a2[]=$row;
foreach($a1 as $row1) {
foreach($a2 as $row2) {
echo $row1['name'].$row2['surname']."<br/>";
}
}
You can do with a simple query
select a.name, b.surname
from names as a
FULL JOIN surnames as b

Why doesn't my loop echo for all iterations?

I'm trying to make a tag cloud system getting its values from PHP/SQL but it seems to work erratically, only giving a handful of the expected results. What's causing this odd behaviour?
As far as I can tell it should loop through a total of 20 times (0-19) and each time it adds a string into an array.
The system starts out by getting the 20 most popular tags from my database in descending order, once its got this I create a string and set the font size. This string is then stored in an array and is echoed out using a random number array giving a random order to the cloud.
I then increase the value of i for my loop iteration whilst decreasing the font size for the next less popular tag.
<h1>Tag Cloud</h1>
<?php
$sql = "SELECT * FROM tags ORDER BY count DESC";
$tags_query = mysqli_query($db_conx, $sql);
$i = 0;
$tag_array = array();
$tag_size_max = 36;
$tag_size_min = 16;
$numbers = range(0, 19);
shuffle($numbers);
do {
$row = mysqli_fetch_array($tags_query, MYSQLI_ASSOC);
$tag = $row["tag"];
$tag_count = $row["count"];
$tag_array[] = "<p style='font-size:".$tag_size_max."px; padding:0px;'>".$tag."</p>";
echo $tag_array[$numbers[$i]];
$i++;
$tag_size_max--;
} while ($i < 20);
?>
You can see it kind of working in the footer of my site http://www.vwrx-project.co.uk
It seems that you're trying to echo $tag_array element with index which isn't yet in the array itself.
You would probably need two loops - first to fill the $tag_array, and another one to echo them.
Do you have proper ERROR_LEVEL - there should be some notices about missing indexes - at least if I'm ready your code correctly ;)
Something like this:
// fill the array
for ($i=0; $i<20; $i++) {
$row = mysqli_fetch_array($tags_query, MYSQLI_ASSOC);
$tag = $row["tag"];
$tag_count = $row["count"]; // this seems to be unused
$tag_array[] = "<p style='font-size:".$tag_size_max."px; padding:0px;'>".$tag."</p>";
}
// echo the array
for ($i=0; $i<count($tag_array); $i++) {
echo $tag_array[$numbers[$i]];
}
I think the problem occurs in the following line
echo $tag_array[$numbers[$i]];
when you push to the array
$tag_array[] = "<p style='font-size:".$tag_size_max."px; padding:0px;'>".$tag."</p>";
you get an index for each tag , for example
[0] =>"<p style='font-size:".$tag_size_max."px; padding:0px;'>".$tag."</p>";
[1] =>"<p style='font-size:".$tag_size_max."px; padding:0px;'>".$tag."</p>";
for every iteration
and then in the following line you echo a random element (probably different form the one you just created )from the array by using the $number array which is not ordered after shuffling it.
I suggest you shuffle the results from the database first with
$results = array();
while($row =mysqli_fetch_array($tags_query, MYSQLI_ASSOC))
{
array_push($results, $row);
}
shuffle($results);
and then create a "normal" loop for printing in the tags using the results array.
Also if you need only 20 tags why not adding LIMIT 20 to your query to simplify the code?
Hope it helps

Query results stored into one variable

I've read through some other posts that were similar but I can't seem to get a good implementation of them. I'm calling a php script from another program that needs the results returned in one variable, space or comma separated. The php connects to a db (no problem there) and runs a query that will return 2 to 6 or so matching rows. I need those results together in one variable but can't seem to get it.
Here's where I'm stuck.
$t = "SELECT user FROM call_times WHERE client='$clientid' AND start <= $date AND end >= $date";
$result = mysql_query($t) or die(mysql_error());
while ($row = mysql_fetch_array($result)) {
$temp = $row['user'];
}
echo $temp;
The query runs fine, but you can see from the code what I'm trying (and failing) to do in the lower part. I need $temp to hold a list of results (ex: 5567889 57479992 4335780 (each of which is a different entry in user column)).
Thanks so much!
$array = array();
while ($row = mysql_fetch_array($result)) {
$array[] = $row['user'];
}
$string = implode(" ", $array);
Now $string has the space-separated values of the user column.
Good luck!
Try group_concat() and you won't need PHP to manipulate the results.

MYSQL PHP while loop, do something if there aren't a given amount of rows returned

I'm trying to figure out the best way to do something like this. Basically what I want to do (in a simple example) would be query the database and return the 3 rows, however if there aren't 3 rows, say there are 0, 1, or 2, then I want to put other data in place of the missing rows.
Say my query returns 2 rows. Then there should be 1 list element returned with other data.
Something like this:
http://i42.tinypic.com/30xhi1f.png
$query = mysql_query("SELECT * FROM posts LIMIT 3");
while($row = mysql_fetch_array($query))
{
print "<li>".$row['post']."</li>";
}
//(this is just to give an idea of what i would likkeee to be able to do
else
{
print "<li>Add something here</li>";
}
You can get the number of items in the resultset with mysql_num_rows. Just build the difference to find out how many items are "missing".
There are three ways I can think of, get the row count with mysql_num_rows, prime an array with three values and replace them as you loop the result set, or count down from three as your work, and finish the count with a second loop, like this:
$result = db_query($query);
$addRows = 3;
while ($row = mysql_fetch_assoc($result){
$addRows--;
// do your stuff
}
while ($addRows-- > 0) {
// do your replacement stuff
}
If you dont find a row, Add extra information accordingly.
$query = mysql_query("SELECT * FROM posts");
for($i=0;$i<3;$i++){
$row = mysql_fetch_array($query);
if($row){
print "<li>".$row['post']."</li>";
}
//(this is just to give an idea of what i would likkeee to be able to do
else{
print "<li>Add something here</li>";
}
}
Assuming you store the rows in an array or somesuch, you can simply do some padding with a while loop (depending how you generate the other data):
while (count($resultList) < 3) {
// add another row
}

Easy method to print something, only once inside while loop?

I want to fetch information from one table and loop that until it's done, with the help of a while loop. Although, I want one column to be printed only once inside the loop.
There's two solutions I've come up with...
<?php
$i = 0;
// while loop start
if($i == 0){
// stuff to print
$i++;
}
// while loop end
?>
And ofcourse, I could just make another query before the while loop.
But these methods really aren't too efficient. Is there a less messy way to do this?
Actually, I'd be okay with running another query before the while loop, if it didn't get so messy, and perhaps if I could just re-use the query intended for the loop (I fetch everything from the table). I tried experimenting with mysql_fetch_field, but I'm not sure I get how it works, or if that even helps here * embarrassed *
Currently, the code looks like so:
$fetch = mysql_query("SELECT *
FROM `pms`
JOIN `pm_conversations` ON pms.ConvID = pm_conversations.ID
WHERE `ConvID`='".$_GET['id']."'");
$i = 0;
while($print = mysql_fetch_array($fetch)){
if($i == 0){
echo $print['Subject'];
$i++;
}
<table>
<th><?=$print['From']?>, <?=$print['DateSent']?></th>
<tr><td><?=$print['Message']?></td></tr>
</table>
}
If I understand your question correctly, I think you've got the right idea. I'm guessing you want to print something extra the first iteration (like maybe column headers using the array keys)?
$cnt= 0;
while($row = mysql_fetch_assoc($res)) {
if(0 == $cnt++) {
// first iteration only
}
// all iterations
}
Or, if I'm totally off a better description of what you're trying to do and the real world situation would help.
Have you thought about do...while? It has all of the benefits of while, plus it allows for code to conditionally happen before the first iteration.
$res = mysql_fetch_array( $resource );
// run the magical run once query/functionality/bunnies/whatever
// Hey, I'm tired. Let there be bunnies.
do
{
// put the regular while loop constructs in here;
}
while( $res = mysql_fetch_array( $resource ) );
$rs = mysql_query("SELECT * FROM tbl");
$row = mysql_fetch_array($rs);
do {
echo $row['column_name'];
} while($row = mysql_fetch_array($rs));
I don't know if this is what you need. Hope this one helps. =]

Categories