## Friday, 26 September 2014

### PHP: another generator example: primes

G'day:
Duncan has mused me again. He's reworking his Project Euler exercises that he'd previously done in CFML, and is now implementing in PHP. In yesterday's exercise he was looking at prime numbers: "Project Euler: problem 7 (PHP)". I thought there was scope for another exercise in using PHP generators in this for me (see previous: "PHP: generators").

So I've come up with this implementation:

``````<?php
// primes.php

function createPrimeSequence(\$length=-1)
{
\$primes = [];
\$potential = 1;
while (\$length==-1 || sizeof(\$primes) < \$length) {
\$potential++;
\$upperThreshold = sqrt(\$potential);
foreach(\$primes as \$prime){
if (\$prime > \$upperThreshold){
break;
}
if (\$potential % \$prime == 0){
continue 2;
}
}
\$primes[] = \$potential;
yield end(\$primes);
}
}

\$primesSequence = createPrimeSequence();

for (\$i=1; \$i <= 20; \$i++){
echo \$primesSequence->current() . " ";
\$primesSequence->next();
}

echo "<hr>";
foreach(createPrimeSequence(10) as \$prime){
echo "\$prime ";
}

``````

The prime calculation logic is pedestrian so I'll ignore that, the new conceit here is that I've added a `\$length` argument to define a... well... length to the sequence, rather than it just continuing forever, as it did in the Fibonacci example. This means I can use it directly in a `foreach()` loop.

Oh, this outputs:

``` 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 ```

`2 3 5 7 11 13 17 19 23 29 `

New stuff I learned whilst doing this:

• how PHP emulates optional arguments by being able to specify a default. It seems one cannot have a truly optional argument though.
• `sqrt()` is PHP's square root function.
• Both `break` and `continue` can exit multiple levels of looping, by specifying a number of levels to exit from (default is `1`). Here I use `continue 2` to break out of the inner `foreach()` loop, but also jump out of the current iteration of the `while()` loop.
• the `\$array[]` syntax is shorthand for `array_push(\$array)`
• `end()` returns the last entry in an array, differing from `array_pop()` as it leaves the array intact.
There's nothing earth-shattering here, but I was pleased with the result, and I've definitely warmed to the idea of generators.

--