PHP - Explain this while/for loop to me - php

I'm new to PHP and I am stuck trying to understand this basic while/for loop. There's a couple of things I just wanted to clarify. Here is the code:
while ($row = $sth->fetch (PDO::FETCH_NUM))
{
print ("<tr>\n");
for ($i = 0; $i < $sth->columnCount (); $i++)
{
print ("<td>" . htmlspecialchars ($row[$i]) . "</td>\n");
}
print ("</tr>\n");
}
I know the while is evaluating for true, so it's getting the result set of the query, and then printing the tags.
However I'm stuck on the
for ($i = 0; $i < $sth->columnCount (); $i++)
I know that the first expression evaluates once, the second evaluates at the beginning and only moves on if it's true, and the third increments by +1. But what exactly is this doing in literal terms and why is it "columnCount"?

This is a PDO database setup.
In literal terms, the $row is a row fetched from the database, from code that lives above in a statement which didn't make your cut. It then sends an iterator into every field of the row (getting its number from the columnCount function(http://php.net/manual/en/pdostatement.columncount.php), and prints out some html.
Generally, this kind of iterator is 'less-than-ideal' code for several reasons. Generally, coding practices in PHP prefer to use foreach instead of a for iterator unless one actually needs the count as we pass through, ostensibly why the fetch is done as FETCH_NUM, although it is never used.
while ($row = $sth->fetch())
{
print ("<tr>\n");
foreach ($row as $key=>$value)
{
print ("<td>" . htmlspecialchars($value) . "</td>\n");
}
print ("</tr>\n");
}

What that line does is making it possible to iterate on each column of the specific $row. $sth->columnCount() returns the number of columns for what seems to be a table data structure.
On the other hand, the for loop will execute the print statement i times, where i will be 0 when starting and will be increasing itself to be as the number of columns returned by $sth->columnCount() minus 1.
Why minus 1?
Because usually in programming you start counting from 0 instead of 1.
So $row[0] represents the 1st column of your row, $row[1] represents the 2nd column, and so on, until you reach the last column which is $row[$sth->columnCount() - 1]

The for loop is starting at the beginning of the dataset and evaluating until it reaches the end of the dataset.
The dataset will always start at 0, until $i is no longer less than the value of columnCount() it will continue.
$sth is some instantiated object (variable) which has a method called columnCount(). That method likely returns the total number of columns which $sth is representing.
It may also help to say that this for loop can be rewritten as a while loop:
$i = 0;
while($i < $sth->columnCount()) {
// do something
$i++;
}

this will iterate through all fields of one row.
columnCount()returns the number of fields in your statement.
So if your statement is:
SELECT a,b,c,d FROM test;
columnCount() return 4.

Related

using php for loop for mysqli_fetch_array

I want to use for loop instead of using the conventional while loop
Like this one (psuedo code):
$list = mysqli_fetch_array($result);
for($x = 0; $x < sizeof($list); $x++){
echo $x;
}
Is this possible?
There's no reason why you can't use a while loop. That being said, when you now use sizeof($list), you will get the number of columns selected from the query (this $list variable has as many elements as columns was selected). You will therefor attempt to loop (and ouput the count of) the number of columns you fetched.
Instead, you might want to do something like this below - fetch the number of rows based on mysqli_num_rows(), which is exactly that - the number of rows returned by the query.
for ($x = 0; $x <= mysqli_num_rows($result); $x++) {
$row = mysqli_fetch_array($result);
var_dump($row);
}
Although, the standard way - and in my opinion the best way - of doing it is via while.
while ($row = mysqli_fetch_array($result)) {
var_dump($row);
}

Array_sum of a fetch_row

I am attempting to get the summation of a set of float values in a column of a table. I did a select query that pulls five sets of integers. A while function with a fetch_row is used to get the array. I use a foreach function to get the sum, however, the echo or printf does not give me one single variable. Instead I get an ever increasing value as each integer is added to the summation of the values before it. I have tried the array_sum, which doesn't work either. Please help! I have looked at every possible question in Stackoverflow.
<?php
//Check if at least one row is found
if($results2->num_rows > 0) {
//Loop through results and fetch as an array
$total = 0;
while($rows = $results2->fetch_row()){
foreach($rows as $sum)
$total += $sum;
printf($total.'<br/>');
}
}
?>
You're printing the total inside the loop, so you see all the subtotals. If you just want to see the final result, print it when the loop is done.
foreach ($rows as $sum) {
$total += $sum;
}
printf("%d<br/>", $total);
Also, when you use printf, the first argument is a format string. The values come after, and they get substituted into the format.
You can also use array_sum:
printf("%d<br/>", array_sum($rows));
Note that these are summing up all the columns in each row, not a single column in the whole table.

How to split SQL query results into chunks in 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

Get next value of MySQL statement inside while

I'm putting values from the database inside a while into an array. Now I wan't to check - inside the while - if the next ID is the same as just outputed. If it isn't my thought is to put the ID inside the array.
Is there any possibility to do this? To check a the next output of a query in a while?
$result = mysql_query("SELECT * FROM $postmeta ORDER BY post_id ASC")
or die(mysql_error());
$basArray = array();
while($row = mysql_fetch_array( $result )) {
$innerArray[$row['meta_key']] = $row['meta_value'];
$basArray[$row['post_id']] = $innerArray;
// Above post_id I want to check if it is the same as the "next coming"
}
Greetings
I would usually just store the most recent ID in a variable, and check it at the top of the while loop. In pseudocode, like this:
$old_row_id = -1; // any value that can't legitimately appear
while ($row = fetch_array($result)) {
if ($old_row_id == $row['id']) {
// logic to follow if IDs are the same
} else {
// logic to follow if IDs are different
}
// logic to follow in either case, if any
$old_row_id = $row['id']; // update variable for the next run through
}
If you really do need to change the behaviour for a particular row according to what happens in the next row, I recommend that you actually effect that change in the following run through the loop, when you check the new row ID against the old one.
Alternatively, you can loop through the resultset twice: the first time putting the rows into a 2-dimensional array so that you can easily reference difference rows by number. Then the second time, you actually do whatever you wanted to do in the first place, and you can reference "the next row" by using [$i + 1] rather than [$i]. (Of course then you have to be careful about the final row, because then the offset [$i + 1] doesn't work.)

Unexpected result in mysql_fetch_array

I am using a complex join statement to get data from my 'items' table where 'column1' is equal to the value of table2.ID
This is in a mysql_query() statement, and it should return 3 rows.
Now my understanding is that by using
$array=mysql_fetch_array($queryresult);
I can then loop through each 'row' using a
foreach($array as $output) {
echo $output['ID'];
}
This is however not returning what i want. Using print_r on $output is outputting non-sensical information.
So, yes it is ver much back to basics, but obviously i have missed the point.
You need to use while loop:
while($row = mysql_fetch_array($queryresult)){
// handle each row
}
This is how I do it. This is by far not the end all solution... Just an example of how I do it.
$result = mysql_query($query, $dbconnect) or trigger_error("SQL", E_USER_ERROR);
$i = 0;
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
echo $row["questionId"];
echo $row["questionText"];
echo $row["questionReview"];
$i++;
}
http://php.net/manual/en/function.mysql-fetch-array.php
$array has a single row in it when you get to the loop, so when you say $output['ID'] you are one level deeper than you are expecting, walking through the columns instead of each row. When the ids don't exist or are translating to integers, thats where the nonsense comes in.
Use while($row = mysql_fetch_array($queryresult)) to walk through each row in the result set, then access the column values from $row['id'], $row['name'], etc. It will return false when there are no more rows.
The result will always be a single flat array with a single row per index id, regardless of the join dimensions.

Categories