On Wed, 5 Mar 2025 at 23:14, Rob Landers <rob@bottled.codes> 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. >
I have read and reread this RFC, and I am struggling to see 1. What problem does this solve that anonymous classes <https://www.php.net/manual/en/language.oop5.anonymous.php> do not? 2. As with any syntax change and new operator there needs to be very careful consideration, do we need a new operation, or could `::` if the parent is static or `->` if the class is initialized? 3. The idea that extending the parent class doesnt no inherit the child classes doesnt make sense to me. As then if you extend a parent class and call a function of that class which could rely on the existence of an inner class, I can see a lot of headaches caused by this exact scenario. As a developer, if I extend a class, I expect the entire dependance of that class to be inherited, otherwise the extending class won't work.