Recursion and Variadic Functions
Pageturn's categories nest: Fiction contains Science Fiction, which contains Space Opera, and nobody knows how deep it will go. And a "total of these prices" function should accept two prices or twenty. Two function techniques handle these: a function that calls itself, and a function that takes any number of arguments.
The rule
Recursion needs a base case; variadics gather extras into an array.
Recursion means a function calling itself on a smaller piece of the problem. It always needs two parts:
- a base case that answers directly, without calling itself;
- a recursive case that calls itself on something closer to the base case.
<?php
function countdown(int $n): void
{
if ($n === 0) { // base case
echo "Launch sale!";
return;
}
echo $n, " ";
countdown($n - 1); // smaller problem
}
countdown(3); // 3 2 1 Launch sale!Nested data is where it shines. Counting every category in a tree of arrays means "count this one, plus everything inside each child", and each child is the same kind of problem.
Forget the base case, or fail to move towards it, and the function calls itself until PHP runs out of memory for the call stack.
Variadic functions accept any number of arguments. Put ... before the last parameter, and PHP gathers the extra arguments into an array:
function sumPrices(float ...$prices): float
{
return array_sum($prices);
}
echo sumPrices(9.99, 7.50); // 17.49
echo sumPrices(); // 0- The variadic parameter must be last, and there can be only one.
- It can follow ordinary ones:
function tag(string $label, string ...$titles). - Called with nothing extra, it is simply an empty array.
The same ... works the other way at a call, spreading an array into separate arguments: sumPrices(...$prices).
The shortcut
For recursion, write the base case first, then make sure every call moves towards it. For variadics, read ... as "the rest, as an array".
The function
function fact(int $n): int { return $n <= 1 ? 1 : $n * fact($n - 1); }
Drills
Answer fast — trust the rule.
What happens to a recursive function with no base case?
What is fact(5) using the function above?
Inside function tag(string $label, string ...$titles), what is $titles for tag("New", "Dune", "Emma")?
Which declaration is valid?
Remember
- Recursion needs a base case; variadics gather extras into an array.
- Shortcut: write the base case first; read
...as "the rest, as an array". - Trap: every recursive call must move closer to the base case, and the variadic goes last.
