Lesson 61 of 100
Functions15 min5 checksPHP 8.5

Unpack Function Arguments with the ... Operator

Learn how the ... operator spreads an array into a function call, how it interacts with defaults and named arguments, and practice it in a small exercise.

01 · THE IDEAREAD → TRY → LEARN

Why unpack arguments?

Sometimes the values a function needs already sit in an array: a row of parsed input, a configuration list, or the result of another function. Writing $row[0], $row[1], $row[2] by hand is noisy and breaks as soon as the array grows. PHP's ... operator solves this. Placed in front of an array or Traversable inside a call, it expands the elements into separate arguments.

Do not confuse this with the variadic parameter function sum(...$numbers). That form collects arguments into an array when a function is declared. Unpacking is the opposite direction: it spreads an array into arguments when a function is called. They are often used together, but they are different jobs.

The basic form

The arguments in a call are evaluated left to right and assigned to parameters in order. With unpacking, the first array element becomes the first argument, the second becomes the second, and so on.

Example
<?php
function add(int $a, int $b): int
{
    return $a + $b;
}

$pair = [4, 6];
echo add(...$pair), "\n";
echo add(...[1, 2]), "\n";
Output
10
3

You can unpack a variable or an array literal. The function does not know the values came from an array; it just receives two arguments.

Mixing with ordinary arguments

You may write normal arguments before an unpacked array, and you may unpack more than one array in the same call. Defaults still apply: if the array supplies fewer values than there are parameters, the remaining parameters fall back to their default values. If a required parameter receives nothing, PHP throws an ArgumentCountError.

Example
<?php
function label(string $prefix, string $name, string $suffix = ''): string
{
    return $prefix . $name . $suffix;
}

$rest = ['Ada', '!'];
echo label('Hi ', ...$rest), "\n";
$parts = ['Hi ', 'Bob'];
echo label(...$parts), "\n";
Output
Hi Ada!
Hi Bob

In the first call the literal 'Hi ' fills $prefix, then the array fills $name and $suffix. In the second call the array has only two items, so $suffix keeps its default empty string.

String keys and named arguments

If the array has string keys, each key is treated as a parameter name. This works because PHP supports named arguments. Order then does not matter, but every key must match a real parameter, and a key must not repeat a parameter that already received a value. Since PHP 8.1 you can also write a named argument after an unpacked array, provided it does not overwrite something already unpacked.

Example
<?php
function box(int $w, int $h, int $d = 1): int
{
    return $w * $h * $d;
}

echo box(...['h' => 3, 'w' => 2]), "\n";
echo box(...[2, 3], d: 4), "\n";
echo json_encode([box(...[5, 5])]), "\n";
Output
6
24
[25]

The first call uses keys to fill $w and $h. The second unpacks two positional values and names $d explicitly. The third relies on the default depth of 1.

Common mistakes

  • Passing the array itself. box($dimensions) sends one array argument to an int parameter and causes a TypeError. You need box(...$dimensions).
  • Too few values. An array with one element cannot satisfy two required parameters.
  • Too many values. For a user-defined function without a variadic parameter, extra positional arguments are ignored, which can hide bugs. Unknown string keys, however, raise an error.
  • Conflicting names. A named argument that targets a parameter the unpacked array already filled throws an Error.
  • Forgetting types. Unpacked values are still checked against parameter types in the usual way.

Exercise contract

The starter file already defines a helper volume(int $w, int $h, int $d = 1): int. Your job is to write boxVolume(array $dimensions): int. It receives a list of two or three integers and must return the volume by passing the list to volume() using unpacking. A two-item list uses the default depth of 1, so [2, 3] gives 6 and [2, 3, 4] gives 24. Zero is a valid dimension and produces 0. The tests check the returned integer, not printed output.

Recap

Use ... in a call to spread an array into arguments. Positional elements fill parameters in order, string keys fill parameters by name, and defaults cover whatever is left. Combine it with ordinary and named arguments when needed, and remember that you are spreading values, not changing the function itself.

Before you start

Functions · Arrays · Types

You’ll practice
  • Pass positional argument arrays to functions
  • Implement and test a deterministic PHP 8.4 function
Your task

Make boxVolume() pass all 5 checks. Run your code as often as you like, then check your answer.

exercise.phpSaved in this browserPHP 8.5
CONSOLE & CHECKS● Ready

Ready when you are

Your output will appear here.
Make it work. Then make it pass.

PHP loads on your first run. Each check starts fresh. Your code stays in this browser; clearing site data removes your progress. A check or the task looks wrong? Report a problem with this exercise.