Named arguments for constructors — making object creation readable
Concept
Named arguments (PHP 8.0) allow passing arguments to a function by parameter name rather than position. This makes call sites more readable, enables skipping optional parameters in the middle of a signature, and makes code self-documenting when parameters aren't obviously identifiable from their values alone.
Syntax: functionName(paramName: value). Named and positional arguments can be mixed, but positional arguments must come before named ones.
Particularly useful for constructors: When creating objects with many optional properties, named arguments avoid the "seven booleans" problem — new Config(true, false, true, false, ...) is opaque, while new Config(debug: true, cache: false) is self-documenting.
Skipping optional parameters: array_slice($arr, 0, preserve_keys: true) — skip $length (omit it entirely) and pass preserve_keys by name. Previously this required passing null for $length, which is less clear.
Array spread of named args: PHP 8.1 allows $fn(...['name' => 'Alice', 'age' => 30]) — spreading an associative array as named arguments. Useful for calling functions with parameter lists computed at runtime.
Limitations: Named arguments can't be used with variadic functions' variadic parameters. They're also not supported in some older extensions' built-in functions (though most core functions support them in PHP 8+).
Code Example
<?php
declare(strict_types=1);
// Basic named arguments
function createUser(string $name, string $email, string $role = 'user', bool $active = true): array
{
return compact('name', 'email', 'role', 'active');
}
// Positional — opaque
$user1 = createUser('Alice', 'alice@ex.com', 'admin', true);
// Named — clear intent
$user2 = createUser(
name: 'Bob',
email: 'bob@ex.com',
role: 'editor',
active: false,
);
// Skip optional parameters — you can skip 'role', only pass 'active'
$user3 = createUser('Carol', 'carol@ex.com', active: false);
// $role takes default 'user', only 'active' is changed
// Built-in function with named args
$arr = ['a', 'b', 'c', 'd', 'e'];
// Skip $length (use null position), pass preserve_keys by name
$slice = array_slice(array: $arr, offset: 1, preserve_keys: true);
// [1 => 'b', 2 => 'c', 3 => 'd', 4 => 'e']
// htmlspecialchars — no more memorizing flag order
$clean = htmlspecialchars(
string: $userInput,
flags: ENT_QUOTES | ENT_HTML5,
encoding: 'UTF-8',
);
// Constructor with named args — DTO creation
class HttpRequest
{
public function __construct(
public readonly string $method,
public readonly string $uri,
public readonly array $headers = [],
public readonly string $body = '',
) {}
}
$request = new HttpRequest(
method: 'POST',
uri: '/api/users',
body: '{"name":"Alice"}',
headers: ['Content-Type' => 'application/json'],
);
// Spread associative array as named args (PHP 8.1)
$params = ['name' => 'Dave', 'email' => 'dave@ex.com', 'role' => 'viewer'];
$user4 = createUser(...$params); // named args from associative array