Three dots in PHP
First-Class Callable Syntax, Variadic function & Argument unpacking

The three dots have three different meanings in PHP.
- First-class callable syntax
- Variadic function
- Argument unpacking
First-class Callable Syntax [since PHP 8.1]
This syntax is used to create Closure objects (anonymous function) from callable (any expression that can be called
in the PHP grammar).
That means, you could store a function or method in a variable and pass it around as a parameter.
$snakeCase = static fn($s): string => strtolower(preg_replace('/\B([A-Z])/', '_$1', $s));
$upperCase = strtoupper(...);
function helloWorldFrom(Closure $closure): void {
echo $closure('HelloWorld');
}
helloWorldFrom($snakeCase); // => hello_world
helloWorldFrom($upperCase); // => HELLOWORLD
In the previous snippet, both $snakeCase and $upperCase are Closure objects.
An anonymous function is always a Closure object, while the PHP native functions like strtoupper are callable
expressions, which are transformed into a Closure object using the ... operator.
We can use the
...operator to create aClosureobject not only from functions but also from static/non-static methods from class instances.
Variadic function
A variadic function doesn't have a fixed arity, that means, it can take an indeterminate number of arguments; in the
end, the parameter will behave like an array.
The variadic argument MUST be at the end of the parameter list.
function foo(string $string, int ...$numbers): void
{
echo sprintf('%s [%s]', $string, implode(', ', $numbers));
}
foo('Foo'); // => Foo []
foo('Foo', 1); // => Foo [1]
foo('Foo', 1, 2); // => Foo [1, 2]
foo('Foo', 1, 2, 3, 4, 5); // => Foo [1, 2, 3, 4, 5]
It is also possible to explicitly the type of all parameters that the variadic function expects to receive. In case some argument doesn't match with the type that was defined in the function signature, it won't work.
Argument unpacking via ...
Arrays and traversable objects can be unpacked into argument lists when calling functions by using the ... operator.
This is also known as the splat operator in other languages.
function add(int $a, int $b, int $c): void
{
echo $a + $b + $c;
}
$numbers = [2, 3];
add(1, ...$numbers); // => 6
While variadic function and argument unpacking both work like a kind of array, the functionality of each one is
practically the opposite.
While the variadic function allows to receive multiple values and inside of it, it behaves like an array; the argument
unpacking is about transforming an array into multiple variables.
The following snippet is a valid PHP code.
echo (fn(int ...$n) => array_sum($n))(...)(...[1, 2, 3]); // => 6
The same code but a bit more readable.
function add(int ...$n): void
{
echo array_sum($n);
}
$numbers = [1, 2, 3];
$f = add(...);
$f(...$numbers); // => 6
The three dots in PHP let you work with functions and methods in a more flexible way.