PHP Splat Operator
last modified May 21, 2025
In this article, we explore PHP's splat operator (...
), also known
as the spread operator. Introduced in PHP 5.6, this operator provides two main
functionalities: capturing variable-length argument lists in functions (argument
unpacking) and unpacking arrays into individual elements.
The splat operator simplifies working with variable numbers of arguments and makes array manipulation more expressive. It's particularly useful for creating flexible APIs and combining arrays.
The advantages of PHP's splat operator are:
- Variadic Functions: Accept unlimited arguments without using func_get_args()
- Array Unpacking: Merge arrays or pass array elements as individual arguments
- Type Safety: Can specify type hints for variadic parameters
- Cleaner Code: More readable than array_merge or argument counting
- Flexibility: Works with both positional and named arguments (PHP 8.0+)
By using the splat operator, developers can write more flexible and expressive functions while maintaining clean, readable code.
Basic variadic functions
The splat operator allows functions to accept a variable number of arguments
by prefixing a parameter with ...
. These arguments are then available as an
array within the function.
<?php declare(strict_types=1); // Simple variadic function function sumAll(...$numbers): float { return array_sum($numbers); } echo sumAll(1, 2, 3) . "\n"; echo sumAll(1.5, 2.5, 3.5, 4.5) . "\n"; // With type hints (PHP 7.0+) function concatenate(string ...$strings): string { return implode(' ', $strings); } echo concatenate('Hello', 'there', 'from', 'PHP') . "\n"; // Mixing regular and variadic parameters function createPerson(string $name, int $age, ...$extraInfo): array { return [ 'name' => $name, 'age' => $age, 'extra' => $extraInfo ]; } print_r(createPerson('Alice', 30, 'Developer', 'London', 'alice@example.com')); // Comparison with old-style variadic functions function oldSumAll() { $numbers = func_get_args(); return array_sum($numbers); } echo oldSumAll(1, 2, 3) . "\n";
This example shows the splat operator used in variadic functions. The
sumAll
function accepts any number of arguments, while
concatenate
enforces string types. The createPerson
function demonstrates mixing regular and variadic parameters.
Argument unpacking
The splat operator can unpack arrays into individual arguments when calling functions. This is useful when you have an array of values that need to be passed as separate arguments to a function.
<?php declare(strict_types=1); // Function that takes three parameters function formatDate(int $day, string $month, int $year): string { return "$day $month $year"; } $dateParts = [15, 'June', 2025]; echo formatDate(...$dateParts) . "\n"; // With associative arrays (PHP 8.0+) function createUser(string $name, string $email, int $age = 18): array { return compact('name', 'email', 'age'); } $userData = ['name' => 'Alice', 'email' => 'alice@example.com', 'age' => 30]; print_r(createUser(...$userData)); // Unpacking multiple arrays function mergeConfigs(array ...$configs): array { return array_merge(...$configs); } $defaults = ['timeout' => 30, 'debug' => false]; $custom = ['debug' => true, 'log_level' => 'error']; $merged = mergeConfigs($defaults, $custom); print_r($merged); // With generators function generateNumbers(int $start, int $end): Generator { for ($i = $start; $i <= $end; $i++) { yield $i; } } $numbers = [...generateNumbers(1, 5)]; print_r($numbers);
This demonstrates array unpacking with the splat operator. The formatDate
example shows positional unpacking, while createUser
demonstrates named
argument unpacking (PHP 8.0+). The mergeConfigs
function shows variadic
unpacking, and the generator example converts yielded values to an array.
Array operations with splat
The splat operator simplifies many array operations by providing a concise way to merge arrays or insert multiple elements into an array at once.
<?php declare(strict_types=1); // Merging arrays $front = ['a', 'b', 'c']; $back = ['x', 'y', 'z']; $combined = [...$front, ...$back]; print_r($combined); // Inserting elements $middle = ['d', 'e', 'f']; $fullAlphabet = [...$front, ...$middle, ...$back]; print_r($fullAlphabet); // With associative arrays (PHP 8.1+) $defaults = ['color' => 'red', 'size' => 'medium']; $overrides = ['color' => 'blue', 'price' => 10]; $result = [...$defaults, ...$overrides]; print_r($result); // Creating new arrays with additional elements $numbers = [1, 2, 3]; $moreNumbers = [0, ...$numbers, 4, 5]; print_r($moreNumbers); // Combining with array_merge $array1 = [1, 2, 3]; $array2 = [4, 5, 6]; $array3 = [7, 8, 9]; $merged = array_merge($array1, $array2, $array3); $mergedWithSplat = [...$array1, ...$array2, ...$array3]; var_dump($merged === $mergedWithSplat); // true
These examples show how the splat operator simplifies array manipulation. It
provides a more readable alternative to array_merge
and allows for
flexible array construction by spreading elements from multiple arrays.
Practical Use Cases of the Splat Operator
The following examples demonstrate five practical applications of the splat operator, each accompanied by code and detailed explanations to illustrate its power and utility in real-world PHP development.
<?php declare(strict_types=1); // 1. Flexible Logging with Contextual Data function debugLog(string $message, ...$context): void { $timestamp = date('Y-m-d H:i:s'); $contextJson = !empty($context) ? json_encode($context) : ''; echo "[$timestamp] $message $contextJson\n"; } debugLog('User logged in', ['user_id' => 123, 'ip' => '192.168.1.1']); // 2. Modular Data Processing Pipeline function processData(array $data, callable ...$processors): array { $result = $data; foreach ($processors as $processor) { $result = array_map($processor, $result); } return $result; } $numbers = [1, 2, 3, 4, 5]; $processed = processData( $numbers, fn($n) => $n * 2, fn($n) => $n + 1, fn($n) => $n ** 2 ); print_r($processed); // 3. Configuration Merging with Safe Overrides function createConfig(array $defaults, array ...$overrides): array { $config = $defaults; foreach ($overrides as $override) { $config = array_merge($config, $override); } return $config; } $appConfig = createConfig( ['debug' => false, 'timeout' => 30], ['debug' => true, 'environment' => 'production'] ); print_r($appConfig); // 4. Flexible Data Transfer Objects (DTOs) class ProductDTO { public string $name; public float $price; private array $extra; public function __construct(string $name, float $price, array $extra = []) { $this->name = $name; $this->price = $price; $this->extra = $extra; } public function getExtra(string $key): mixed { return $this->extra[$key] ?? null; } public function getAllExtra(): array { return $this->extra; } } $product = new ProductDTO('Laptop', 999.99, ['category' => 'Electronics', 'stock' => 5]); print_r($product->getAllExtra()); // 5. Dynamic SQL Query Building class QueryBuilder { private array $parts = []; public function select(string ...$columns): self { $this->parts['select'] = $columns ?: ['*']; return $this; } public function where(string ...$conditions): self { if (!empty($conditions)) { $this->parts['where'] = $conditions; } return $this; } public function getQuery(): string { $select = implode(', ', $this->parts['select'] ?? ['*']); $where = isset($this->parts['where']) ? ' WHERE ' . implode(' AND ', $this->parts['where']) : ''; return "SELECT $select FROM products$where"; } } $query = (new QueryBuilder()) ->select('id', 'name', 'price') ->where('price > 100', 'stock > 0') ->getQuery(); echo $query . "\n";
The debugLog
function exemplifies how the splat operator
facilitates flexible logging with contextual data. By allowing any number of
context arrays to be passed as arguments, the function can serialize them into
JSON for inclusion in log messages. This is particularly useful for debugging
user actions or system events, as it accommodates varying amounts of
metadata—such as user IDs or IP addresses—without requiring predefined
parameters. The timestamp ensures logs are traceable, making this approach ideal
for monitoring application behavior in development or production environments.
The processData
function demonstrates the splat operator's role in
creating a modular data processing pipeline. It accepts an array of data and a
variable number of callable functions, each applied sequentially to transform
the data. In the example, numbers are doubled, incremented, and squared in a
chain of operations. This design promotes reusability, as developers can easily
add or modify processors without altering the core function. It's particularly
valuable for tasks like data normalization or transformation in ETL (Extract,
Transform, Load) processes.
Configuration management is streamlined with the createConfig
function, which uses the splat operator to merge multiple override arrays into a
default configuration. This ensures that default settings, such as debug mode or
timeouts, are preserved while allowing flexible overrides for specific
environments. The use of array_merge
with variable arguments
prevents unintended overwrites, making it a robust solution for managing
application settings across different deployment scenarios.
The ProductDTO
class showcases how the splat operator supports
flexible Data Transfer Objects. By storing additional attributes in a private
extra
array, the class avoids dynamic property creation, ensuring
compatibility with modern PHP's strict standards. The getExtra
and
getAllExtra
methods provide safe access to these attributes,
allowing developers to handle variable data—like product categories or stock
levels—while maintaining type safety and encapsulation.
Finally, the QueryBuilder
class illustrates the splat operator's
utility in building dynamic SQL queries. By accepting variable numbers of
columns and conditions, it creates a fluent interface for constructing queries.
The example selects specific columns and applies multiple conditions, producing
a clean SQL statement. This approach simplifies database interactions, making it
easier to build complex queries while keeping the code readable and
maintainable, especially in applications with dynamic data requirements.
PHP's splat operator (...
) is a versatile tool for working with
variable-length argument lists and array manipulation. Key points to remember:
- Variadic Functions: Accept any number of arguments with
...$param
- Argument Unpacking: Pass array elements as individual arguments with
...$array
- Array Operations: Merge arrays or create new arrays with spread elements
- Type Safety: Variadic parameters can be type-hinted for argument validation
- Named Arguments: Works with named arguments in PHP 8.0+
- Performance: Generally efficient but consider memory with very large arrays
- Readability: Often clearer than
func_get_args
orarray_merge
The splat operator is particularly valuable when creating flexible APIs, processing variable-length data, or combining arrays. It makes PHP code more expressive while maintaining good performance characteristics.
Author
List all PHP tutorials.