RSSAmplifier

Mountain Of Code · Apr 7, 2026

PHP Generics Extension

0
Sign in to vote or save

This page cannot be shown here. You can still read it on the original site — the toolbar below keeps your place in the directory.

I'm a believer in adding as much type information as you can when programming. It gives IDEs and static analysis tools so much power to find bugs or give useful suggestions. I work with PHP, which has historically been a very loose language. It's gotten better over the years and now has typed properties, return types, unions, intersections, DNF , etc. What we don't have is generics: class Thing <…

I'm a believer in adding as much type information as you can when programming. It gives IDEs and static analysis tools so much power to find bugs or give useful suggestions.

I work with PHP, which has historically been a very loose language. It's gotten better over the years and now has typed properties, return types, unions, intersections, DNF, etc.

What we don't have is generics:

class Thing<T> {
    private array<T> $widgets;
}
new Thing<Widget>();

It gets talked about a lot, and the PHP Foundation did some research into the options a couple of years ago. I believe that the only viable way forward for PHP is erased generics paired with a separate static analysis tool like PHPStan. This is basically what TypeScript is.

I didn't want to create a separate transpiler tool like TypeScript, I wanted to keep the same DX PHP devs are used to. I wondered if erased generics could be achieved via an extension.

I've written very little C in my time, let alone a whole PHP extension, but with the help of Claude and the PHP Internals Book, I had a working extension in a couple of hours. It strips out the generics syntax on the fly at runtime. It supports classes, methods, properties, functions, closures, nesting, namespaces, etc:

class Container<T> {
    public array<Widget>|null $widgets;
    public Collection<Widget|Thingy> $widgetsOrThingys;
    public Factory<Maker<Widget>|null> $nesting;
    public function __construct(
        public array<Widget>|null $data,
    ) {}
    public function find(): array<Widget>|null {}
}
new Container<Widget>();
function foo(array<\App\Models\Widget> $items) {}
$closure = function(): array<Widget> {};

Code and installation instructions are in the repo, just remember it's very much a prototype to explore what's possible, there will be bugs 🦗

What's Next?

It needs a shed load more testing, and to really be useful it needs an accompanying PHP Storm plugin. This isn't going to work:

Links

Read on /php-generics-extension

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.