Modern PHP Features You Should Be Using

Modern PHP Features You Should Be Using

PHP

PHP has come a long way from its "ugly duckling" reputation. With releases from PHP 8.0 through 8.3, the language has become genuinely elegant and powerful. I'm a big fan of PHP and really don't get the hate. Never have, and probably never will, as it improves with every release. But if you're still writing PHP like it's 2015, here are the Modern PHP features you're missing out on.

1. Named Arguments

Gone are the days of passing null placeholders just to reach the argument you care about. Named arguments let you skip straight to what matters.

// Old way
array_slice($array, 0, null, true);

// With named arguments
array_slice(array: $array, offset: 0, preserve_keys: true);

The result is self-documenting code. It's much easier to read at a glance. This is particularly handy when working with built-in PHP functions that have long, easy-to-forget signatures - no more hunting through the docs just to remember argument order.

2. Match Expressions

The match expression is a switch done right. It uses strict comparison, has no fall-through, and returns a value. The classic switch statement can't say the same. And I've honestly never been a big fan of the switch statement, so this is a huge improvement.

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

No more forgetting to add a break. No more accidental fall-throughs. It's clean, less code and makes sense. Match expressions shine anywhere you're mapping one value to another - HTTP status codes, user roles, configuration states - and the strict type checking means fewer silent bugs.

3. Enums

PHP 8.1 introduced native enums. They replace the old pattern of class constants and magic integers. They're type-safe, IDE-friendly, and can implement interfaces.

enum Status: string {
    case Active = 'active';
    case Inactive = 'inactive';
    case Pending = 'pending';
}

$user->status = Status::Active;

For domain modelling, this is a massive upgrade over what came before. Anywhere your application has a fixed set of states - order statuses, payment methods, user roles - enums make those values explicit, type-checked, and impossible to misuse. We use them in MySQL, so it makes sense to use them in PHP too.

4. Readonly Properties

Readonly properties let you declare a value once. After construction, it can never change. It's a simple concept with a big impact on code reliability.

class User {
    public function __construct(
        public readonly int $id,
        public readonly string $email,
    ) {}
}

PHP 8.2 took this further with readonly classes. The constraint applies to every property automatically. This is invaluable for value objects and data transfer objects - things like a Money, Address, or ApiResponse class where mutation after creation makes no sense and would only cause bugs.

5. Constructor Property Promotion

Constructor property promotion cuts the boilerplate of defining, declaring, and assigning class properties down to a single line. Instead of repeating yourself three times, you do it once. Who can complain about that?

// Old way
class User {
    public int $id;
    public string $email;

    public function __construct(int $id, string $email) {
        $this->id = $id;
        $this->email = $email;
    }
}

// With constructor promotion
class User {
    public function __construct(
        public int $id,
        public string $email,
    ) {}
}

It pairs especially well with readonly properties, letting you build immutable value objects and DTOs with very little code. If you find yourself writing lots of small data classes - command objects, query results, API responses - this will save you a lot of typing and keep those classes easy to scan.

6. String Helper Functions

PHP 8.0 quietly solved one of the language's longest-running irritants. For years, checking whether a string contains or starts with a value meant reaching for strpos() and writing awkward comparisons. Now there are dedicated functions for the job.

// Old way
if (strpos($url, 'https') === 0) { ... }
if (strpos($haystack, 'needle') !== false) { ... }

// New helpers
if (str_starts_with($url, 'https')) { ... }
if (str_contains($haystack, 'needle')) { ... }
if (str_ends_with($filename, '.php')) { ... }

They're readable, intention-revealing, and eliminate an entire class of off-by-one bugs. It's the kind of function that you'll reach for constantly - validating URLs, checking file extensions, parsing input strings, filtering log entries. Simple, but you'll use them every day.

Wrapping Up

Modern PHP is fast, expressive, and type-safe. Features like enums, readonly properties, match expressions, and named arguments aren't just syntactic sugar. They lead to genuinely better code - easier to maintain and harder to break.

If you haven't already, now is a great time to update your projects to PHP 8.2 or later. There's a lot to take advantage of, and the upgrade path is smoother than you might expect.

Comments (0)

No comments yet — be the first to share your thoughts.

Leave a comment

0/500 characters

Your comment will be checked before it appears publicly.