PHP 7 twist on an old problem: FizzBuzz


Two of the nice new features of PHP 7 is Type Declarations and Return Type Declarations, both coercive and strict. Obviously having typing is a benefit for both debugging and clearer code.

Considering the “FizzBuzz”  [1]   problem, these new features can work to our advantage both in function inputs, and function outputs. Added to return types is iterable which, as you’ll see, will come in handy.

A simple implementation of “FizzBuzz” in PHP can be done in different ways, the most straight forward perhaps being iterating over the desired range in a loop. A problem can arise, however, if the range is large, as, it will need to be created in memory. A very large array will consume a lot of memory. Thanks to the miracle of generators   [2], we can create a range of arbitrarily large size without incurring the memory problem.

With that in mind, our simple implementation of “FizzBuzz” will allow the input of any size range, where a range here is defined as starting at the integer 1, and conaining all numbers up to and including an ending integer greater than 1. You’ll note in the code the inclusion of both Parameter Types, and a Return Type, for the generator function.

<?php
declare(strict_types=1);
  /**
   * PHP v7 or greater
   *
   * Extensible, memory safe ("array") sequence
   * 
   */
  function genSeq( int $start, int $end ) : iterable {
    /* 
     * logically, end must be greater than zero as a consequence
     * of these checks
     */
    if( $start <= 0 ) {
      throw new LogicException("Start must be above zero");
    }
    if ( $start >= $end ) {
      throw new LogicException("Start must be less than End");
    }
      
    for( $i = $start; $i <= $end; $i++ ) {
      yield $i;
    }
  }
  
  $gen = genSeq(1, 100);
  foreach( $gen as $i ) {
    switch( $i ) {
      case $i % 15 == 0:
        echo "FizzBuzz\n";
        break;
      case $i % 5 == 0:
        echo "Buzz\n";
        break;
      case $i % 3 == 0:
        echo "Fizz\n";
        break;
    }
  }
?>

1. FizzBuzz asks that, in evaluating a range of numbers, if the number is evenly divisible by 3, output “Fizz”. If the number is evenly divisible by 5, output “Buzz”. If the number is evenly divisible by 15, output “FizzBuzz”. 
2. Added in PHP 5.5 

Leave a comment