DEV Community

spO0q
spO0q

Posted on

PHP: toward Generics

For now, PHP doesn't have native support for generics, like Collection<T>.

Those structures are quite common in other programming languages, like #C or Java, and improve type safety.

A long-desired feature at runtime

Docblock annotations and static analysis tools (e.g., Psalm, PHPStan) can simulate generics behavior.

However, it's a third-party implementation, so it's not standard.

Such feature would enforce proper types dynamically, not just at static analysis time.

This would also make code more maintainable and expressive, leading to a better developer experience.

Generics vs. collections vs. arrays

You may consider PHP arrays as collections. However, it can contain anything and everything :

$theUniverse = [ 'string', null, [1,2,3,'ok'], new MyObject(), ]; 
Enter fullscreen mode Exit fullscreen mode

It's very handy but can quickly pollute the code base, as you often need to manually check the types within a loop.

There's no native way to strict type-hinting them in signatures.

That's why we use docblock annotations:

/* * @var array<string> $names */ $names = ['Alice', 'Eve']; 
Enter fullscreen mode Exit fullscreen mode

But it can be tedious to document an associative array of mixed types:

/** * @var array<int, string|null|array<int, int|string>|MyObject> $theUniverse */ $theUniverse = [ 'string', null, [1, 2, 3, 'ok'], new MyObject(), ]; 
Enter fullscreen mode Exit fullscreen mode

Besides, it's prone to bugs.

Even in this more simple and realistic example:

$users = [ new User('Alice'), new User('Eve'), 'oops', // boom ]; foreach ($users as $user) { echo $user->getID(); } 
Enter fullscreen mode Exit fullscreen mode

There's no way to trust $users. That's why we'd rather use custom collections to limit bugs:

$userCollection = new UserCollection(); $userCollection->add(new User('Alice')); $userCollection->add(new User('Eve')); foreach ($userCollection->getItems() as $user) { echo $user->getID(); } 
Enter fullscreen mode Exit fullscreen mode

However, with something like <Collection<User>, type info would be available at runtime.

The code would be more reusable, extendable, and standardized.

Higher complexity vs. better design

While Generics could be beneficial, this does not come without questions for all PHP developers, not just core teams.

We won't cover this here, but there are some concerns with type inference and performance.

You may read the post called the PHP foundation State of Generics and Collections (see Useful links) for more details.

Such feature would be pretty cool but it should also force us to think better.

Using arrays of mixed types is not exactly the best implementation, and it's usually a trade-off, for example, with legacy code.

Wrap up

Many third-party libraries already help write custom collections and enforce type safety, but it's not really scalable.

With Generics, we could leverage a new standard to make our code more readable and maintainable.

Useful links

Top comments (0)