On Wed, Mar 12, 2025, at 11:10, Rob Landers wrote:
> On Thu, Mar 6, 2025, at 00:11, Rob Landers wrote:
>> Hello PHP Internals,
>> 
>> I'd like to introduce my RFC for discussion: 
>> https://wiki.php.net/rfc/short-and-inner-classes
>> 
>> This RFC defines a short class syntax as well as the ability to nest classes 
>> inside another class. This introduces an unprecedented amount of control, 
>> flexibility, and expressiveness over how objects are used and instantiated 
>> in PHP. There is a PR (https://github.com/php/php-src/pull/17895) that 
>> implements this functionality -- all test failures are related to 
>> different/new/incorrect error messages being generated. However, the core 
>> functionality exists to take for a test ride.
>> 
>> So, what do I mean by "unprecedented amount of control"? With this change, 
>> you can declare an inner class as private or protected, preventing its usage 
>> outside of the outer class:
>> 
>> class User {
>>   private class Id {}
>> 
>>   public function __construct(public self::Id $id) {}
>> }
>> 
>> In the above example, the class `User` is impossible to construct even 
>> though it has a public constructor (except through reflection) because 
>> User::Id is private; User::Id cannot be instantiated, used as a type hint, 
>> or even via `instanceof` outside of the User class itself. This example 
>> isn't practical but demonstrates something that is nearly impossible in 
>> previous versions of PHP, where all classes are essentially publicly 
>> accessible from anywhere within the codebase.
>> 
>> As a number of inner classes will probably be used as DTOs, the RFC 
>> introduces a "short syntax" for declaring classes, which enhances 
>> expressiveness, even allowing the usage of traits, all in a single line:
>> 
>> // declare a readonly Point, that implements Vector2 and uses the Evolvable 
>> trait
>> readonly class Point(public int $x, public int $y) implements Vector2 use 
>> Evolvable;
>> 
>> When combined with inner classes, it looks something like this:
>> 
>> class Pixel {
>>   public readonly class Point(public int $x, public int $y) implements 
>> Vector2 use Evolvable;
>> }
>> 
>> // Create a new pixel point with property $x and $y set to 0
>> $p = new Pixel::Point(0, 0);
>> 
>> There are far more details in the RFC itself, so please check it out. I'm 
>> quite excited to hear your thoughts!
>> 
>> — Rob
>> 
>> PS. I know I tend to rush into things, but I want to make it clear that I'm 
>> not rushing this -- I've learned from my mistakes (thank you to those who 
>> have given me advice). I'm going to do this right.
>> 
>> 
> 
> Hello internals,
> 
> I've made some major updates to the text of the RFC to clarify behaviors and 
> revisited the implementation (which is still under development, though I hope 
> to have a draft by the end of this weekend). Here's a broad overview of what 
> has changed in inner classes:
> 
> - Accessing inner classes is done via a new token: ":>" instead of "::".
> - Inner classes may now be infinitely nested.
> - Inner classes may be declared `abstract`.
> - Documented changes to ReflectionClass.
> - Usage of `static` to refer to inner classes is restricted to prevent 
> accidental violations of LSP.
> 
> Otherwise, there are not any big changes, but a lot of time was spent 
> clarifying behavior and expanding on the reasoning for those decisions in the 
> RFC itself.
> 
> — Rob

For those who are interested, I've opened the PR that enables this feature: 
https://github.com/php/php-src/pull/18069

— Rob

Reply via email to