Why does the value of this array element resolve to zero? - php

I'm working on pagination for my website, yet I'm stuck on the following piece of code. I've been messing around with it for at least an hour, and can't seem to wrap my head around what's going on with the output.
Of course the if statement executes once.
And as expected the first echo ... returns 1.
However, for some reason the second echo ... returns 0 as a float instead of <div>1</div> as a string...
$rowCount = 5;
$pgCount = ceil($rowCount / 10);
$pgParamArray["page"] = $pgCount;
$pgArray = array("", "", "", "", "");
for ($i = 0; $i < 5; $i++) {
if ($pgParamArray["page"] - $i > 0) {
echo $pgParamArray["page"] - $i;
$pgArray[$i] = "<div>" . $pgParamArray["page"] - $i . "</div>";
echo $pgArray[$i];
}
}
I have tried setting $pgArray as array() and array($v1, $v2, $v3, $v4, $5) with no luck.
Even though var_dump($pgParamArray) returns float, I tried converting $rowCount, which is initially a string from the database, to a number anyways. No dice again.
echo $pgArray["0"] also returns 0.
var_dump($pgArray[0]) also returns float.
var_dump($pgArray) obviously returns array.
However, var_dump($pgArray) returns array(5) { [0]=> string(7) ...
I have absolutely zero idea why $pgArray[0] returns 0, yet var_dump($pgArray) returns array(5) { [0]=> string(7) .... That makes zero sense to me. Anybody know why $pgArray[0] is resolving to 0?

Wrapping your statement in parenthesis seems to work for me:
$pgArray[$i] = "<div>" . ($pgParamArray["page"] - $i) . "</div>";
Without the parenthesis, it seems that the value breaks completely; the page doesn't print the <div> tags at all, but rather just adds a trailing 0 to the already printed 1.
I would assume that it's due to how PHP processes string concatenation, though I wouldn't be able to give you an exact answer as to why this happens. Just to be safe, I'd always either store any equations in variables before you pass them in, or perform all operations inside of parenthesis.
That way, you won't have weird encounters like this (for example):
echo "<div>" . 1 + 1 . "</div>"; // returns 1
echo "<div>" . (1 + 1) . "</div>"; // returns 2

You need to group the arithmetic part as mentioned in the accepted answer:
$pgArray[$i] = "<div>" . ($pgParamArray["page"] - $i) . "</div>";
To understand what's going on here, you need to run it on the command line:
php > $rowCount = 5;
php >
php > $pgCount = ceil($rowCount / 10);
php >
php > $pgParamArray["page"] = $pgCount;
php >
php > $pgArray = array("", "", "", "", "");
php >
php > for ($i = 0; $i < 5; $i++) {
php {
php { if ($pgParamArray["page"] - $i > 0) {
php {
php { echo $pgParamArray["page"] - $i;
php {
php { $pgArray[$i] = "<div>" . $pgParamArray["page"] - $i . "</div>";
php {
php { echo $pgArray[$i];
php {
php { }
php {
php { }
10</div>
php >
As you can see, the output of echo $pgParamArray["page"] - $i; is 1, immediately followed by 0</div> as the contents of $pgArray[$i].
So the real issue is, what is happening to the <div> in
$pgArray[$i] = "<div>" . $pgParamArray["page"] - $i . "</div>";
After seeing the real output, the answer is a little more obvious now: it's a grouping issue. PHP is simply taking it left to right:
((("<div>". $pgParamArray["page"]) - $i) . "</div>")
((("<div>" . 1 ) - $i) . "</div>")
((("<div>1") - $i ) . "</div>")
((( 0 ) - $i ) . "</div>")
((( 0 ) - 0 ) . "</div>")
((( 0 )) . "</div>>")
((( "0</div>" )))

Related

While loop hangs when decrement variable is set in PHP

the while loop hangs with the decrement variable ($j--) set after the echo command..
$j = 10;
while($j>-10)
{
if($j==0)continue;
echo (10/$j) . "<br>";
$j--;
}
but works well when set before if statement
$j = 10;
while($j>-10)
{
$j--;
if($j==0)continue;
echo (10/$j) . "<br>";
}
Can anyone explain pls?
When $j==0 it skips the rest of the code in the loop because of the continue so it never gets to the $j-- in the first code.
This means that $j will never get below 0 and the loop will never finish.
As in the second code it will always decrements it before the test, it will eventually get to -10.
Try adding
echo $j.PHP_EOL;
as the first line in the loop (assuming you are using the CLI version) to see what is happening.
Another slightly different version of your code can be used to ONLY avoid the echo when $j is 0, instead of doing the continue...
$j = 10;
while($j>-10)
{
if($j != 0) {
echo (10/$j) . "<br>";
}
$j--;
}

PHP foreach update the variable outside of foreach and use it inside again

I want to update the variable outside of the foreach scope and use it again in the condition inside it, but the variable in condition stays the same with the initial value. It gets updated outside, but the condition inside still uses the old value for comparing. How can the variable inside, used in condition get updated as well?
$total = 5.00000008;
for($i = 0; $i < count($values); $i++) {
if($total == $values[$i]){
$total += 0.00000001;
}
}
I am referring to the $total variable inside if condition, it doesn't get updated.
In a comment, #NanThiyagan wrote:
"your question was not clear.but your code works fine refer
eval.in/1050113"
Check out the output. It says 5.0000001. This might give you a hint that php automatically does something to round up your value.
Read this: http://php.net/manual/en/language.types.float.php
And pay attention to the part:
"So never trust floating number results to the last digit, and do not
compare floating point numbers directly for equality."
In this article they approach the problem with an implicit precision: https://www.leaseweb.com/labs/2013/06/the-php-floating-point-precision-is-wrong-by-default/
Like this:
ini_set('precision', 17);
echo "0.1 + 0.2 = ". ( 0.1 + 0.2 ) ."\n";
$true = 0.1 + 0.2 == 0.3 ? "Equal" : "Not equal";
echo "0.1 + 0.2 = 0.3 => $true\n";
I think you might not be fully aware of what's happening inside the loop.
The variable $total is being updated every time the condition is true. And the condition variable $total is updated as well.
Here's an example so you can see it happening:
$values = [5.00000008, 5.00000009, 5.00000007];
$total = 5.00000008;
for($i = 0; $i < count($values); $i++) {
echo ((string) __line__ . ' => ' . (string) $total . " (current total)\n");
if($total === $values[$i]){
echo ((string) __line__ . ' => ' . (string) $total . " (before increment)\n");
$total += 0.00000001;
echo ((string) __line__ . ' => ' . (string) $total . " (after increment)\n");
}
}
And here's the code tested: https://3v4l.org/EJkNG
I am referring to the $total variable inside if condition, it doesn't get updated.
Of course it gets updated.
Simply echo $total inside the loop to find out.
<?php
$values = [5.00000007, 5.00000008, 5.00000009];
$total = 5.00000008;
for ($i = 0; $i < count($values); $i++) {
if ($total == $values[$i]) {
$total += 0.00000001;
}
echo $total . "\n";
}
Output:
5.00000008
5.00000009
5.0000001
See for yourself at https://3v4l.org/RBHa3

Controlling for-loop output

Is it possible to control a for-loop when it reaches a certain condition?
Explanation:
I'm retrieving the folder path to a collection of images from a database: these images are then printed out via a for-loop. What I would need to do is control how these images are displayed on the page (say, 5 images per row).
As of now, the for-loop prints out 40 images in a single row, which makes you scroll to the furthest right of the page.
Is there a solution for controlling the for-loop, as in for instance, after 5 successful loops, echo out a < br >? Here's a vulgar thought:
for ($i = 1; $i < $rows; $i++) {
$path = $image[$i];
$folder_path = $path['folder_path']; //since it's an array
echo '<img src="' . $folder_path . '">';
//pseudocode
if ($i == 5) {
echo '<br>';
...continue with the loop
}
}
I know the pseudocode looks crazy, but that's pretty much what I need to do: loop for x amount of instances, add something, then continue.
As per #m69's comment, the best option would be to use the % (modulus) comparison operator. As explained by the PHP docs:
$a % $b returns the remainder of $a divided by $b.
So, in your case:
for ($i = 0; $i < $rows; $i++) {
$path = $image[$i];
$folder_path = $path['folder_path']; //since it's an array
echo '<img src="' . $folder_path . '">';
if ($i % 5 == 0) { //do this if $i divided by 5 has a remainder of 0
echo '<br>';
}
}
As a side note, you should set $i to 0 at the beginning of your for loop, assuming $rows is set to the number of rows returned from your query. Setting it to 1 will keep it from iterating through the last row, because $i will == 40 (assuming 40 rows), and so will NOT be < 40.
The same loop. The condition for inserting the is ($i % 5 == 0), which means (if this element is the fifth one of his series) will be useful for you.
<?php
for ($i = 1; $i < $rows; $i++) {
$path = $image[$i];
$folder_path = $path['folder_path'];
echo '<img src="' . $folder_path . '">';
if ($i % 5 == 0) {
echo '<br>';
}
}

Adding constant to PHP loop variable [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
How to add something to PHP's loop variable and check the result? I have this simple code:
<?php
for ($i=0; $i<5; $i++) {
echo "Time: " . $i + 1 . "<br/>";
}
?>
The displayed result in the page:
1
1
1
1
1
But if there's no addition with 1, the result is correct. How to do this addition?
You concat in your question use this:
<?php
for ($i=0; $i<5; $i++) {
echo "Time: " . ($i + 1) . "<br/>";
}
?>
Change this line:
echo "Time: " . $i + 1 . "<br/>";
to this:
echo "Time: " . ($i + 1) . "<br/>";
Put the calculation in brackets:
<?php
for ($i=0; $i<5; $i++) {
echo "Time: " . ($i + 1) . "<br/>";
}
?>
While adding parentheses to give the addition a higher precedence is an option, the easiest way is to turn $i + 1 into an expression, to be resolved to a singular value and then pass it to echo, using comma's:
for ($i=0; $i<5; $i++)
{
echo "Time: " , $i + 1 , "<br/>";
}
But the shortest way to write this is:
for ($i=0;$i<5;)//don't increment here
{
echo 'Time: ', ++$i, '<br/>';//increment here, and make sure to pre-increment
}
Or, more readable (and IMHO therefore better):
for($i=1;$i<6;$i++)
{//start with one, so you needn't increment in the loop body!
echo 'Time: ', $i, '<br/>';
}
Leaving out conactenation is marginally faster, but you'll hardly notice that. It's just an alternative. Think of the two options as this (if you're familiar with C++):
int i = 0;
std::stringstream toPrint;//create string-stream
toPrint << "Time: " << ++i << "<br/>";//pass substrings/int chunks to stream
std::COUT << toPrint.str();//create single string, and pass to output-stream
But that's just silly, considering you're actually creating a stream, just to pass your substrings/ints to, only to pass the resulting string to the output stream. You might as well pass all chunks to the output stream directly:
std::<COUT << "Time: " << ++i << "<br/>"; //pass string, int and string to output
Think of echo as a language construct (which it is) that is your access-point to the STDOUT stream. Whe concatenate a string manually, of you can just pass it to the stream as-is? without any overhead?
As an asside, you can get the output you need in just 2 lines of code, without (explicitly) looping and incrementing a variable:
$vals = range(1,5);//create array 1, 2,3, 4, 5
//repeat format Time: %d<br/> for every index in $vals
vprintf(str_repeat('Time: %d <br/>', count($vals)), $vals);
//pass resulting format to vprintf, allong with the array of values
The output is the same. In case you're thinking about using this: don't. It's just for fun, and an example of how you can take compacting code a bit too far
<?php
for ($i=1; $i <= 5; $i++) {
echo "Time: " . ($i) . "<br />";
}
You are looking to do something like this :
<?php
for ($i=0; $i<5; $i++) {
$j=$i+1;
echo "Time: " . $j . "<br/>";
}
?>
Like DanFromGermany suggested, why not start with $i one higher than currently?
Also if you have to do calculations, the meaning of the var usually differs from it's starting point. So for readability and reusability do what Munjal proposed, but leave out the concatenation;
<?php
for ($i=0; $i<5; $i++) {
$laterTime = $i + 1;
echo "Time: {$laterTime} <br />\n";
}
?>
<?php
for ($i=0; $i<5; $i++) {
$i++;
echo "Time: ".$i. "<br/>";
}
?>
or if you insist on concatenation
<?php
for ($i=0; $i<5; $i++) {
echo "Time: " .++$i. "<br/>";
}
?>

How do I make a foreach loop display items on more than one column?

I'm trying to modify a joomla module and I have a small problem (which is not joomla related, thus no code necessary).
I have a foreach loop which has a block of code in it which displays an article. It repeats itself as many times as you set it up in the admin panel. I want to add the feature that makes this module display items on more than 1 column. All I need is the perk, I think I have everything else covered.
Basically how do I modify a simple foreach loop so that it displays articles on more than one column?
Instead of this
a
b
c
d
e
I want this
a ........ d
b ........ e
c
You can get the count of results and work from the middle if you're sticking with tables
$half_count = floor(count($entries) / 2);
for($i=0;$i<$half_count;$i++)
{
echo '<tr>';
echo '<td>' . $entries[$i] . '</td>';
echo '<td>' . (isset($entries[$half_count + $i]) ? $entries[$half_count + $i]: '') . '</td>';
echo '</tr>';
}
Here a simple way to do it :
php > $arr = array(1,2, 3, 4, 5, 6, 7, 8, 9, 10);
php > for ($i=0; $i<count($arr); $i+=2) { print $arr[$i] . "\t" . $arr[$i+1] . "\n"; }
1 2
3 4
5 6
7 8
9 10
As far as I know, you won't be able to do it with a foreach statement but with a for.
For example:
$iterations = (count($array_of_items) % 2) ? (count($array_of_items) / 2) + 1 : count($array_of_items) / 2;
for ($i = 0; $i <= $iterations; $i++) {
if (isset($array_of_items[$i+3]))
echo $array_of_items[$i].'........'.$array_of_items[$i+3];
else
echo $array_of_items[$i];
}
Really simple code without so little info but could make the trick!
Instead of outputting in the for loop, I would create two arrays of the articles in the for loop. Then loop through those arrays to create your columns outside of the main loop.
You have little info in the question, but here's something you could use
$arr = array("a","b","c","d","e","f");
for ($i = 0; $i<count($arr); $i++){
echo $arr[$i]." ". $arr[$i+3] ."\n";
if($i == 2){ break;} //Modify 2 as more alphabets are added
}
Outputs
a d
b e
c f
For a generic solution, assuming a packed array....
function show_table($data, $columns)
{
$items=count($data);
$iters=$items/$columns + ($items % $columns) ? 1 : 0;
for ($y=0; $y<$iters; $y++) {
for ($x=0; $x<$columns; $x++) {
$offset=$y*$columns + $x;
if ($offset<$items) print $data[$offset] . ' ';
}
print "\n";
}
}

Categories