Holly

> On Jul 10, 2026, at 10:20 AM, Alex Rock <[email protected]> wrote:
>
> Le 10/07/2026 à 06:38, Holly Schilling a écrit :
>>
>>>
>>> For one, I read only internals and github.  I keep seeing "we talked on 
>>> discord" but there is no reference whatsoever to a php.net 
>>> <http://php.net/>'s discord anywhere i searched for.
>>>
>>> so maybe I would suggest to be a tat bit more descriptive first here too?
>>
>> Yes, this has not been as public of a discussion as it should be, so please 
>> allow me to share some more details here for you and the rest of the 
>> Internals community.
>>
>> There are currently 3 RFCs comprising 3 phases and feature sets to build for 
>> extensions.
>>
>> 1. General Class Extension Syntax: 
>> https://gist.github.com/hollyschilling/f590f3a1e488732eea5b0d8014702276
>> This RFC adds a basic extensions using this syntax:
>> ```
>> extension \DateTimeImmutable {
>>     public function isWeekend():bool {
>>         return in_array((int)$this->format('N'), [6,7],true);
>>     }
>> }
>> var_dump((new DateTimeImmutable('2026-07-11'))->isWeekend());// bool(true)
>> ```
>>
>> 2. Scalar Method Extensions: 
>> https://gist.github.com/hollyschilling/1d247189b8bf45fe044bfbe7fb07dcdb
>> Allow extensions to be applied to scalars, like strings and ints. This has a 
>> lot of code changes to make this work and the blast radius is huge. That’s 
>> why it’s a separate component.
>> ```
>> extension string {
>>     public function length():int {return strlen($this); }
>> }
>>
>> var_dump("hello"->length());// int(5)
>> ```
>>
>> 3. Extension Visibility and Importing: 
>> https://gist.github.com/hollyschilling/dc97ea217302de2f4c9ad7d527aaa65b
>> This adds rules and syntax to be able to import an extension without using 
>> `require_once` (or similar).
>>
>> First, the autoloader needs extensions to have a name, so we give them a 
>> name when declared.
>> ```
>> // vendor/acme/dom-kit/src/traversal.php
>> namespace Acme\DomKit;
>>
>> extension DomTraversal on \DOMElement {
>>     public function firstByClass(string $class): ?\DOMElement {/* ... */ }
>> }
>> ```
>> Then, as we want to use our declared extensions, we import them with a 
>> `use`, similar to normal classes.
>> ```
>> use extension Acme\DomKit\DomTraversal;
>>
>> $el->firstByClass('hero');// resolves here
>> ```
>>
>>>
>>>    I believe I’ve proven out the concept and viability of it in a
>>>    2-phase approach using an extension syntax similar to that of Swift.
>>>
>>>    Before I go into much more detail, what is the general interest
>>>    in adding this to the language?
>>>
>>>
>>> reading the thread, I feel both swift and you aim to the same goal, some 
>>> parts use different approaches but as I am not a user of swift, it may be 
>>> nicer if you could work together,  if desired?
>>>
>>
>> Extension methods allow adding functions to existing classes. As a future 
>> consideration, they can also be used to add readonly virtual properties (No 
>> setter; No storage). This is purely syntactic sugar, but it can be extremely 
>> helpful making code easier to read and increasing code reuse. Think of it as 
>> a Trait that you apply to someone else’s code after the fact.
>>
>> It is also possible to apply an extension to an Interface. While it cannot 
>> be used to implement members of the interface, it can make all classes 
>> implementing that interface have useful methods.
>>
>> The other useful feature is that a class may implement its own version of a 
>> function and the function resolution will go to the class’s implementation 
>> as you might expect.
>>
>> I hope this helps. The 3 links go to the Gists for each phase and a link 
>> from each Gist goes to the implementation for each.
>>
>> I’m happy to answer any additional questions you or anyone else has as you 
>> read through the docs.
>>
>> Holly
>
>
> Thanks for all these links, I think the conversation should start from this 
> thread from now on, to avoid referring to unknown mails or discord channels :)
>
> On the feature itself, I'm not knowledgeable enough on the engine impact, and 
> the concept of Extensions could be a really great addition to PHP, however on 
> the userland-side, things must be extra clear to avoid messing up with 
> potential unidentified edge-cases when declaring or using an extension, and 
> the actual impact on the ecosystem and usage.

There are lots of potential sharp edges here. I believe I’ve addressed them all 
in the code and RFC, but I’m definitely open to having more pointed out.

>
> The RFC about scalar extensions can be deferred and is optional (though very 
> good, but having built-in classes for scalars, but the first RFC and the 
> visibility RFC should be merged and re-thought in order to fix the loading 
> issue. Maybe you could chat with @azjezz about this part, because it's the 
> kind of thing that could be shipped in his "PHP PSL" project (visible there: 
> https://github.com/php-standard-library/php-standard-library)

I’ve never looked much at PHP PSL. I’ll do that.

As far as scalar methods goes, I hate my implementation. I’m not suggesting 
someone else could do better, only that the compromises necessary to implement 
it weren’t worth it. After having implemented it and seen what it demands, I 
think the right choice is Autoboxing with extensions on the box rather than 
ever allowing `$this` to not be an object.

This is a heated topic lately and I don’t pretend to be an expert.


>
> The two other RFCs imply extensions will need to be imported via manual 
> require/require_once calls, therefore package maintainers declaring 
> extensions will have to use the "autoload.files" composer option. It works, 
> but it will add an overhead (wasting time in file load and wasting memory 
> usage) on extensions that are declared but not used.

With the inclusion of the Visibility RFC, explicit `require` or `require_once` 
is not necessary. The `use extension` syntax replaces it. The consequence of 
this is that extension methods are only visible in scopes that explicitly want 
them. This prevents the from polluting globally.

> If autoload was triggered when encountering "use extension", it would have 
> the advantage of being explicit, but it's counter-intuitive: "use" statements 
> shouldn't usually trigger anything and just serve as aliases for symbols 
> referenced in the file, so it's inconsistent with current usage of the "use" 
> keyword.
> And if package maintainers don't use "autoload.files" to avoid the 
> potentially unnecessary overhead, this means that userland code would be 
> forced to write "require_once 'path/to/extension.php'; " in their own files, 
> which is not at all what anyone would expect, and defeats the purpose of 
> having a dependencies manager like Composer in the first place, even though 
> "it works".

The new `use extension` syntax is a slightly different purpose than developers 
are used to with an ordinary `use` declaration, but it follows the same spirit. 
There is a thing not in this file that needs to be brought into scope.

Reply via email to