A separate RFC, Extension Methods, lets you add methods to a class you don't own. Under that proposal, once a file with an extension block runs, its methods work everywhere for the rest of the request. This RFC from Holly Schilling adds a way to limit that. You give an extension a name, and its methods only work in files that import it with use extension.

Why it helps

Global visibility is fine for helpers in your own app, but it's a poor fit for libraries. Two Composer packages that extend the same class would see each other's methods, and so would all of your code, with no way to tell where a method came from. The RFC follows Kotlin here, where you also have to import extensions before you can call them.

How it looks

A library declares a named extension:

// vendor/acme/dom-kit/src/traversal.php
namespace Acme\DomKit;

extension DomTraversal on \DOMElement $el {
    public function firstByClass(string $class): ?\DOMElement { /* ... */ }
}

A file that imports it can call the method:

// app/render.php
use extension Acme\DomKit\DomTraversal;

$el->firstByClass('hero'); // works

A file that doesn't import it can't:

// app/other.php, no import
$el->firstByClass('hero');
// Error: Call to undefined method DOMElement::firstByClass()

The rules

  • An import only applies to code below it in the same file, like other use statements.
  • Visibility depends on where the code was written, not on who called it.
  • You can't alias an import (use extension Foo as Bar is an error), and the grouped use extension Vendor\{A, B} form isn't supported either.
  • Importing isn't loading. The file that declares the extension still has to run. In a Composer project, the package would list that file under autoload.files, so you'd only need the use extension line. A companion RFC would add autoloading for extensions.
  • Unnamed extensions keep working everywhere, as in the base RFC.

The RFC also says imports are stored with the compiled file, so they work with opcache without extra work on each request.

What it means for existing code

Nothing breaks beyond what the base RFC changes, since the new syntax is a parse error today. This RFC only matters if the Extension Methods RFC is accepted.

Where it stands

It's a draft, first written in July 2026, and it doesn't have a discussion thread yet. The planned vote needs a two-thirds majority and would be void if the base RFC is declined.