---
title: "Unpacked, named and array of positional arguments are in a call…"
url: https://www.exakat.io/unpacked-named-and-positional-arguments-are-in-a-call/
date: 2022-10-04
modified: 2023-12-12
author: "dams"
description: "Unpacked, named and positional arguments are in a call... How to handle an array of positional arguments in PHP? Argument spread is the three dots operator, when used with arguments...."
categories:
  - "Code auditing"
tags:
  - "arguments"
  - "variadic"
image: https://www.exakat.io/wp-content/uploads/2022/10/courges.320.jpg
word_count: 920
---

# Unpacked, named and array of positional arguments are in a call…

# Unpacked, named and positional arguments are in a call...

How to handle an array of positional arguments in PHP? Argument spread is the three dots operator, when used with [arguments](https://www.php.net/manual/en/functions.arguments.php). Its primary usage is simple : it stands in front of a variable, and turns an array into a list of arguments.

Recently, while checking the PHP 8.1 migration guide, I realized that [named arguments after argument unpacking](https://www.php.net/manual/en/migration81.new-features.php#migration81.new-features.core.named-arg-after-unpack) was introduced. It just does what it means :

With PHP 8.1, it is possible to provide named arguments after the unpacked arguments. This is an edge case, as, nowadays, named parameters are still a small fraction of method calls. Yet, having this new feature mentioned in the migration guide made me wonder what are the other situations.

Unpacking arguments has to deal with three dots, positional arguments and named arguments. Also, this features is impacted by the structur of the unpacked arrays. Here is a rundown of the various cases, starting with the simpler cases.

## Simple calls

Calling a method with an unpacked array is straighforward. Multiple unpacking may occur in a row : the arguments are then positioned one after the other. We'll see about the content of the unpacked variables later.

### Mixed calls

To combine unpacked variables and normal variables, there are some limitations : the normal arguments have to be put first. Just like for method declarations, three dots come last.

Positionals arguments cannot be used after any three dots. It yields a compile time fatal error `Cannot use positional argument after argument unpacking`.

Until PHP 8.1, named arguments are also forbidden after the three dots. With PHP 8.1, they are allowed and fill their named paramter. This means that the initial unpacked array should not fill that position already.

### Simple arrays

When the array uses integer as index, positional arguments are used.

It is noteworthy that the order of the values is used, without any sorting on the keys. The indexes are simply dropped, and the values order is kept, like this :

### Simple maps

When the array uses string as index, named arguments are used. It works with PHP 8.0 and more recent. Previous PHP versions yield a Fatal error : `Cannot unpack array with string keys`.

Named parameters are checked, including for case. Named parameters that do no exist are met with a Fatal error : `Unknown named parameter $e`.

### Mixed array

It is possible to mix integer and strings index in the unpacked array. It follows the same rules than for arguments. Remember that the arguments are processed in the value order, just like if array_values() was applied, but string index were kept where available.

In particular, all the integer values must be at the first positions in the array, or a Fatal error `Cannot use positional argument after named argument during unpacking`is emited.

Similarly, named parameter cannot overwrite a previously filled spot. It yields a `Named parameter $a overwrites previous argument`.

## Three dots, positional and named parameters

Long are gone the days of simple positional arguments in a method call : nowadays, there are many ways to provide arguments to their right place : positional, named arguments and unpacked arrays.

Current usage reserve three dots usage to methods that accept arbitrary number of arguments. The arguments are all of the same sort, but their actual number is collected at execution time, like for array_merge(), for example.

Other calls tends to stick to one sort only : all positional or all named, with or without array unpacking. This keeps coding readable and simple. Otherwise, no less than four different Fatal errors await in the dark.

Using amy mixed approach with positional, named and unpacked arguments leads to the enforcement of several surprising rules, with errors emerging very late during execution : while overwriting a named parameter is detected at linting time, unpacking an array is only checked at call time.

As often, it is better to keep it simple.