I am learning PHP. I decided to adapt a solution to the famous FizzBuzz problem from Javascript to PHP, just to see how JS and PHP compare.
For those who forgot what the FizzBuzz problem is :
Write a short program that prints each number from 1 to 100 on a new line. For each multiple of 3, print “Fizz” instead of the number. For each multiple of 5, print “Buzz” instead of the number. For numbers which are multiples of both 3 and 5, print “FizzBuzz” instead of the number.
I am using a lot of short-circuit evaluations in the following examples. Here’s the clever solution (not written by me) that I adapted to PHP:
Works great!
Then, for the sake of challenge, I decided to try and rewrite it in one single line. Here’s how I started:
Seems like a good start. My condition in the while loop: if $i is not set set, then I set it to zero, but if it is already set, I skip the first part and check if it’s inferior to 100. As you can see on this picture, my loop works. Since my goal is to write it in one line, I need to increment $i inside my conditional statement, just as with my previous multi-line solution. But when I write $i++ < 100 as before, something weird happens. My loop only runs once and stops.
Very weird indeed. Even weirder, if I use both increments (one in the condition and one in the loop), the loop then works fine, and applies both increments.
I’m puzzled. Is it because there is a safeguard for infinite loops somewhere? With all those short-circuit evaluations, even my IDE PHP Storm says ‘variable $i is probably undefined’. But it gets defined, and my loop works fine under certain conditions. What did I miss ?
EDIT: Here’s the code: Multi-line working FizzBuzz:
$i = 0; while ($i++ < 100) { $msg = ''; ($i % 3) || ($msg = $msg . 'Fizz'); ($i % 5) || ($msg = $msg . 'Buzz'); echo $msg . "n"; }
Weird loop iteration (you can delete the increment either in the loop or in the condition, or leave both to see the different effects):
while ( (!isset($i) && ($i=0 || true) ) || ($i++ < 100) ) { echo $i . "n"; $i = $i +1; }
Advertisement
Answer
if $i is not set set, then I set it to zero
This is not quite right. Here’s what’s going on.
- Your statement
($i=0 || true)
sets$i
toTRUE
. - PHP’s type juggling with print “1” for
"$i"
. Consider$v = TRUE; echo "$v";
to see this in effect. - On the next iteration, your second condition is evaluated as
TRUE < 100
which evaluates toFALSE
, thereby exiting the loop.
So, in order to fix your problem, simply drop the || true
and be on your merry way.