Claude
Skills
Sign in
Back

PHP Modern Features

Included with Lifetime
$97 forever

Use when modern PHP features including typed properties, union types, match expressions, named arguments, attributes, enums, and patterns for writing type-safe, expressive PHP code with latest language improvements.

Writing & Docs

What this skill does


# PHP Modern Features

## Introduction

Modern PHP (7.4+, 8.0+, 8.1+, 8.2+) has evolved dramatically with features that
improve type safety, expressiveness, and developer experience. These additions
transform PHP from a loosely-typed scripting language into a powerful,
type-safe platform for building robust applications.

Key improvements include strict typing, property and parameter types, union and
intersection types, match expressions, named arguments, attributes (annotations),
enumerations, and readonly properties. These features enable clearer intent,
better IDE support, and fewer runtime errors.

This skill covers typed properties, union/intersection types, match expressions,
enums, attributes, named arguments, and patterns for leveraging modern PHP
effectively.

## Typed Properties and Parameters

Type declarations improve code reliability by enforcing types at runtime and
enabling better static analysis.

```php
<?php
// PHP 7.4+ typed properties
class User {
    public string $name;
    public int $age;
    public ?string $email = null; // Nullable
    private array $roles = [];
    protected bool $active = true;
}

$user = new User();
$user->name = "Alice"; // OK
$user->age = 30; // OK
// $user->age = "thirty"; // TypeError

// Constructor property promotion (PHP 8.0+)
class Product {
    public function __construct(
        public string $name,
        public float $price,
        public int $stock,
        private ?string $sku = null
    ) {}
}

$product = new Product("Laptop", 999.99, 10);
echo $product->name; // "Laptop"
// echo $product->sku; // Error: private property

// Return type declarations
function calculateTotal(float $price, int $quantity): float {
    return $price * $quantity;
}

function findUser(int $id): ?User {
    // Return User or null
    return $id > 0 ? new User() : null;
}

function getUsers(): array {
    return [new User(), new User()];
}

// Void return type
function logMessage(string $message): void {
    echo $message . "\n";
}

// Never return type (PHP 8.1+)
function fail(string $message): never {
    throw new Exception($message);
}

// Mixed type (PHP 8.0+)
function process(mixed $value): mixed {
    return $value;
}

// Static return type
class Builder {
    public function setName(string $name): static {
        return $this;
    }

    public function build(): static {
        return new static();
    }
}

// Parameter types
function greet(
    string $name,
    int $age,
    bool $formal = false
): string {
    $greeting = $formal ? "Good day" : "Hello";
    return "$greeting, $name ($age)";
}

// Variadic typed parameters
function sum(int ...$numbers): int {
    return array_sum($numbers);
}

$total = sum(1, 2, 3, 4, 5); // 15
```

Typed properties and parameters catch type errors early and provide clear
contracts for function interfaces.

## Union and Intersection Types

Union types allow multiple type possibilities, while intersection types require
all specified types simultaneously.

```php
<?php
// Union types (PHP 8.0+)
function processId(int|string $id): void {
    if (is_int($id)) {
        echo "Processing integer ID: $id\n";
    } else {
        echo "Processing string ID: $id\n";
    }
}

processId(123);
processId("ABC-456");

// Union type properties
class Response {
    public function __construct(
        public int|string $code,
        public array|string $data
    ) {}
}

// Nullable as union type
function findProduct(int $id): Product|null {
    return $id > 0 ? new Product("Item", 10.0, 5) : null;
}

// Multiple union types
function format(int|float|string $value): string {
    return match (true) {
        is_int($value) => "Integer: $value",
        is_float($value) => "Float: $value",
        is_string($value) => "String: $value",
    };
}

// False pseudo-type in unions
function parseValue(string $input): int|false {
    $result = filter_var($input, FILTER_VALIDATE_INT);
    return $result !== false ? $result : false;
}

// Union types with built-in types
function getData(): array|object|null {
    return ['key' => 'value'];
}

// Intersection types (PHP 8.1+)
interface Loggable {
    public function log(): void;
}

interface Cacheable {
    public function cache(): void;
}

// Function accepting intersection type
function process(Loggable&Cacheable $object): void {
    $object->log();
    $object->cache();
}

class Service implements Loggable, Cacheable {
    public function log(): void {
        echo "Logging\n";
    }

    public function cache(): void {
        echo "Caching\n";
    }
}

// Intersection with union
function handle((Loggable&Cacheable)|null $object): void {
    $object?->log();
}

// DNF types (PHP 8.2+ - Disjunctive Normal Form)
function advanced((Loggable&Cacheable)|(Loggable&Serializable) $object): void {
    $object->log();
}
```

Union types enable flexible parameter acceptance while intersection types
enforce multiple capabilities simultaneously.

## Match Expressions

Match expressions provide pattern matching with strict comparisons and
exhaustive checking, improving upon switch statements.

```php
<?php
// Basic match expression (PHP 8.0+)
$status = 200;

$message = match ($status) {
    200 => "OK",
    404 => "Not Found",
    500 => "Server Error",
    default => "Unknown",
};

echo $message; // "OK"

// Multiple conditions
$result = match ($status) {
    200, 201, 202 => "Success",
    400, 401, 403 => "Client Error",
    500, 502, 503 => "Server Error",
    default => "Unknown",
};

// Match with expressions
$age = 25;

$category = match (true) {
    $age < 13 => "Child",
    $age < 18 => "Teen",
    $age < 65 => "Adult",
    default => "Senior",
};

// Match without default (throws on no match)
function getColor(string $type): string {
    return match ($type) {
        'primary' => '#007bff',
        'success' => '#28a745',
        'danger' => '#dc3545',
        // Missing default throws UnhandledMatchError
    };
}

// Match with complex expressions
enum Status {
    case Draft;
    case Published;
    case Archived;
}

function canEdit(Status $status): bool {
    return match ($status) {
        Status::Draft => true,
        Status::Published => false,
        Status::Archived => false,
    };
}

// Match returning different types
function process(mixed $value): int|string {
    return match (gettype($value)) {
        'integer' => $value * 2,
        'string' => strtoupper($value),
        'array' => count($value),
        default => 0,
    };
}

// Match vs switch strict comparison
$value = "1";

// Switch uses == (loose)
switch ($value) {
    case 1:
        echo "Matches with switch\n"; // Prints
        break;
}

// Match uses === (strict)
$result = match ($value) {
    1 => "Matches with match",
    "1" => "Strict match", // This matches
    default => "No match",
};

echo $result; // "Strict match"
```

Match expressions are safer than switch due to strict comparison and exhaustive
checking requirements.

## Enumerations

Enums provide type-safe sets of possible values, replacing magic strings and
constants with explicit types.

```php
<?php
// Basic enum (PHP 8.1+)
enum Status {
    case Pending;
    case Approved;
    case Rejected;
}

function updateOrder(Status $status): void {
    echo "Order status: " . $status->name . "\n";
}

updateOrder(Status::Approved);

// Backed enum with values
enum Priority: int {
    case Low = 1;
    case Medium = 2;
    case High = 3;
    case Critical = 4;
}

$priority = Priority::High;
echo $priority->value; // 3
echo $priority->name; // "High"

// String-backed enum
enum Role: string {
    case Admin = 'admin';
    case User = 'user';
    case Guest = 'guest';
}

// Enum methods
enum HttpStatus: int {
    case OK = 200;
    case Created = 201;
    case BadRequest = 400;
    case Unauthorized = 401;
    case NotFound = 404;
    case ServerError = 500;

    public function isSuccess(): bool {
        return $this->value >= 200 && $this->value < 300;
    }

    public function isError(): bool {
   

Related in Writing & Docs