M0UNTAIN 0F C0DE

PHP Generics Extension

PHP generics

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