PHP 8 Features — Complete Guide to Named Arguments, Attributes, Readonly
In this tutorial, you will learn about PHP 8 Features. We cover key concepts, practical examples, and best practices to help you master this topic.
PHP 8 introduced major language features including named arguments, attributes, readonly properties, union types, match expression, nullsafe operator, and constructor property promotion.
What You'll Learn
By the end of this tutorial, you'll use PHP 8 named arguments, create and read attributes, use readonly properties, leverage union types, and use the match expression and nullsafe operator.
Why PHP 8 Matters
PHP 8 modernizes the language significantly. Named arguments improve API clarity, attributes replace docblock annotations, and readonly properties enforce immutability.
Real-World Use
A PHP 8 application uses named arguments for query Builder methods, readonly DTOs with constructor promotion, and custom attributes for validation rules, eliminating boilerplate.
PHP 8 Path
flowchart LR
A[PHP Basics] --> B[PHP 8 Features]
B --> C[PHP 8.1 Enums/Fibers]
B --> D[PHP 8.2 Readonly]
C --> E[PHP 8.3/8.4]
B --> F{You Are Here}
style F fill:#f90,color:#fff
Named Arguments
Pass arguments by parameter name instead of position, skipping defaults.
<?php
function createUser(string $name, string $email = "", bool $admin = false, array $tags = []): array {
return compact("name", "email", "admin", "tags");
}
$user = createUser(name: "Alice", admin: true, tags: ["vip"]);
print_r($user);
// Skipped $email defaults to ""
Constructor Property Promotion
Declare and assign properties directly in the constructor signature.
<?php
class User {
public function __construct(
public string $name,
private string $email,
protected bool $admin = false,
private \DateTimeImmutable $createdAt = new \DateTimeImmutable()
) {}
public function getEmail(): string { return $this->email; }
}
$user = new User(name: "Alice", email: "alice@example.com");
echo $user->name;
Attributes
Replace docblock annotations with native PHP attributes.
<?php
#[Attribute]
class ValidationRule {
public function __construct(
public string $rule,
public ?string $message = null
) {}
}
class UserDTO {
public function __construct(
#[ValidationRule("required")]
#[ValidationRule("min:3")]
public string $name,
#[ValidationRule("email")]
public string $email
) {}
}
$reflection = new ReflectionClass(UserDTO::class);
foreach ($reflection->getProperties() as $prop) {
$attrs = $prop->getAttributes(ValidationRule::class);
echo "{$prop->name}: " . count($attrs) . " rules\n";
}
Readonly Properties
Readonly properties can be set once and never changed after initialization.
<?php
class Config {
public readonly string $apiKey;
public readonly int $timeout;
public function __construct(string $apiKey, int $timeout = 30) {
$this->apiKey = $apiKey;
$this->timeout = $timeout;
}
}
$config = new Config(apiKey: "sk-123", timeout: 60);
echo $config->apiKey;
// $config->apiKey = "new"; // Error: Cannot modify readonly property
Match Expression
Match is a strict type-safe alternative to switch that returns a value.
<?php
function getStatusLabel(int $code): string {
return match ($code) {
200 => "OK",
201 => "Created",
301, 302 => "Redirect",
400 => "Bad Request",
401 => "Unauthorized",
403 => "Forbidden",
404 => "Not Found",
500 => "Server Error",
default => "Unknown",
};
}
echo getStatusLabel(404);
Common Mistakes
1. Mixing Named and Positional Arguments
Named arguments must come after positional in PHP 8.0. PHP 8.1 allows mixing but keep consistent.
2. Forgetting Attributes Need #[Attribute] Declaration
Custom attribute classes must be marked with #[Attribute]. Otherwise, Reflection ignores them.
3. Setting Readonly Properties After Construction
Readonly properties can only be set during declaration or in the constructor. Any later assignment throws an error.
4. Misunderstanding Match Strict Comparison
Match uses === (strict) comparison, not == (loose). 0 and "0" do not match.
5. Overusing Named Arguments in Hot Paths
Named arguments have a small performance overhead. Use positional for performance-critical internal calls.
Practice Questions
1. What is constructor property promotion?
A PHP 8 feature that declares and assigns class properties directly in the constructor parameter list.
2. How do you create a custom attribute?
Define a class with #[Attribute] and use #[AttributeName] before classes, methods, or properties.
3. What does readonly do on a property?
Prevents modification after initialization. The property can be set once and is immutable afterward.
4. How is match different from switch?
Match returns a value, uses strict comparison, and throws on unhandled cases without default.
5. Challenge: Create a DTO class using PHP 8 features.
<?php
#[Attribute]
class SerializedName {
public function __construct(public string $name) {}
}
class ProductDTO {
public function __construct(
public readonly string $name,
#[SerializedName("product_price")]
public readonly float $price,
public readonly int $stock = 0,
public readonly ?string $description = null,
) {}
}
FAQ
Mini Project: Request Validation with Attributes
Build a validation system using PHP 8 attributes.
<?php
#[Attribute]
class Validate {
public function __construct(public string $rule) {}
}
class Request {
public function __construct(
#[Validate("required")] public string $name,
#[Validate("email")] public string $email,
#[Validate("min:8")] public string $password,
) {}
}
function validate(object $dto): array {
$errors = [];
$ref = new ReflectionClass($dto);
foreach ($ref->getProperties() as $prop) {
$attrs = $prop->getAttributes(Validate::class);
foreach ($attrs as $attr) {
$rule = $attr->newInstance()->rule;
$value = $prop->getValue($dto);
if ($rule === "required" && empty($value)) $errors[] = "{$prop->name} is required";
if (str_starts_with($rule, "min:")) {
$min = (int) substr($rule, 4);
if (strlen($value) < $min) $errors[] = "{$prop->name} must be at least {$min}";
}
}
}
return $errors;
}
What's Next
PHP 8.1 Enums and Fibers PHP 8.2 Readonly Classes PHP PSR Standards
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro