99## Introduction
1010
1111PHP has steadily evolved to enhance developer productivity and expressiveness,
12- introducing new features such as typed properties, constructor property promotion, and first-class callable syntax.
12+ introducing features such as typed properties, constructor property promotion, and first-class callable syntax.
1313However, defining simple data structures and organizing classes remains verbose.
1414
1515This RFC proposes two related enhancements to PHP:
1616
17- ** Short class syntax** , which allows for defining simple or data-oriented classes in a single line:
17+ ** Short class syntax** , allowing simple or data-oriented classes to be defined in a single line:
1818
1919``` php
2020class Point(int $x, int $y);
2121```
2222
23- This syntax serves as a shorthand for defining classes with constructor property promotion,
23+ This syntax acts as a shorthand for defining classes with constructor property promotion,
2424reducing boilerplate while maintaining clarity.
2525
26- ** Inner classes** , which allows for the ability to define classes within other classes and control the use of inner classes through visibility:
26+ ** Inner classes** , enabling the definition of classes within other classes with visibility control :
2727
2828``` php
2929class Foo {
@@ -35,16 +35,16 @@ class Foo {
3535
3636### Short Class Syntax
3737
38- The proposed syntax for a short class definition is as follows: a keyword ` class ` ,
39- followed by the class name, then a list of properties enclosed in parentheses.
40- Optionally, a list of traits, interfaces, and a parent class may be defined .
38+ The proposed syntax for defining a short class consists of the class keyword,
39+ followed by the class name, and a list of properties in parentheses.
40+ Optionally, traits, interfaces, and a parent class can be specified .
4141
4242``` php
4343
44- // a simple class with two public properties: x and y
44+ // a simple class with two public properties
4545class Point(int $x, int $y);
4646
47- // a more complex readonly class with a parent class, interface, and traits.
47+ // A readonly class with a parent class, interface, and traits
4848readonly class Vector(int $x, int $y) extends BaseVector implements JsonSerializable use PointTrait, Evolvable;
4949```
5050
@@ -62,8 +62,8 @@ readonly public class Vector extends BaseVector implements JsonSerializable {
6262}
6363```
6464
65- Any properties defined within the parenthesis are defined as a property on the class
66- and are automatically ` public ` unless specified otherwise.
65+ Properties inside parentheses are automatically declared as class properties
66+ and default to public unless explicitly specified:
6767
6868``` php
6969// declare $shapes as a private property
@@ -72,33 +72,33 @@ class Geometry(private $shapes) use GeometryTrait;
7272
7373#### Default Values
7474
75- Default values may be provided for properties but only for properties with type hints :
75+ Properties with type hints may have default values :
7676
7777``` php
7878class Point(int $x = 0, int $y = 0);
7979```
8080
8181#### Inheritance and Behavior
8282
83- With class short syntax, no behavior may be defined, yet it can still utilize traits, interfaces, and other classes.
83+ Short classes can extend other classes, implement interfaces,
84+ and use traits, but they cannot define additional methods.
85+ The parent class constructor is overridden and not automatically called.
8486
8587``` php
8688class Point(int $x, int $y) extends BasePoint implements JsonSerializable use PointTrait, Evolvable;
8789```
8890
89- Note that the original constructor from any parent class is overridden and not called by the short syntax.
90-
9191#### Empty Classes
9292
93- Short classes may also be empty:
93+ Short classes may be empty:
9494
9595``` php
9696class Point() extends BasePoint use PointTrait;
9797```
9898
9999#### Attributes
100100
101- Attributes may also be used with short classes:
101+ Attributes can be used with short classes:
102102
103103``` php
104104#[MyAttribute]
@@ -107,7 +107,7 @@ class Password(#[SensitiveParameter] string $password);
107107
108108#### Modifiers
109109
110- Short classes support modifiers such as ` readonly ` , ` final ` and ` abstract ` :
110+ Short classes support readonly, final, and abstract:
111111
112112``` php
113113readonly class User(int $id, string $name);
@@ -119,11 +119,11 @@ abstract class Shape(float $area);
119119
120120#### How it works
121121
122- Short classes are implemented as pure syntax sugar and are compiled as full class definitions.
122+ Short classes are purely syntactic sugar and compile into standard class definitions.
123123
124124### Inner Classes
125125
126- Inner classes are classes that are defined within another class.
126+ Inner classes allow defining classes within other classes, following visibility rules:
127127
128128``` php
129129class Outer {
@@ -141,7 +141,50 @@ $baz = new Outer::PrivateInner('Hello, world!');
141141// Fatal error: Uncaught Error: Cannot access private inner class Outer::PrivateInner
142142```
143143
144- Inner classes have inheritance similar to static properties, allowing you to define rich class hierarchies:
144+ #### Modifiers
145+
146+ Inner classes support modifiers such as ` public ` , ` protected ` , ` private ` , ` final ` and ` readonly ` .
147+ When using these as modifiers on an inner class, there are some intuitive rules:
148+
149+ - ` public ` , ` private ` , and ` protected ` apply to the visibility of the inner class.
150+ - ` final ` , and ` readonly ` apply to the class itself.
151+ - ` static ` is not allowed as a modifier since PHP does not support static classes.
152+ - ` abstract ` is not allowed as an inner class cannot be parent classes.
153+
154+ #### Visibility Rules
155+
156+ Private and protected inner classes are only instantiatable within their outer class
157+ (or subclasses for protected) and may not be used as type hints outside of their outer class.
158+
159+ ``` php
160+ class Outer {
161+ private class PrivateInner(string $message);
162+
163+ public function getInner(): self::PrivateInner {
164+ return new self::PrivateInner('Hello, world!');
165+ }
166+ }
167+
168+ // using a private inner class from outside the outer class, as a type hint is forbidden
169+ function doSomething(Outer::PrivateInner $inner) {
170+ echo $inner->message;
171+ }
172+
173+ // this is ok:
174+ $inner = new Outer()->getInner();
175+
176+ // but this is not:
177+ doSomething($inner);
178+ // Fatal error: Private inner class Outer::Inner cannot be used in the global scope
179+ ```
180+
181+ Just like with other languages that support inner classes,
182+ it is better to return an interface or a base class from a method instead of exposing a private/protected class.
183+
184+ #### Inheritance
185+
186+ Inner classes have inheritance similar to static properties;
187+ this allows you to redefine an inner class in a subclass, allowing rich hierarchies.
145188
146189``` php
147190readonly class Point(int $x, int $y);
@@ -194,61 +237,8 @@ var_dump($t instanceof Geometry); // true
194237var_dump($t instanceof Triangle::FromCoordinates); // true
195238```
196239
197- #### Modifiers
198-
199- Inner classes support modifiers such as ` public ` , ` protected ` , ` private ` , ` final ` and ` readonly ` .
200- When using these as modifiers on an inner class, there are some intuitive rules:
201-
202- - ` public ` , ` private ` , and ` protected ` apply to the visibility of the inner class.
203- - ` final ` , and ` readonly ` apply to the class itself.
204-
205- Thus, an inner class with the modifier ` private readonly ` is only accessible within the class
206- and any instances are readonly.
207-
208- ` static ` is not allowed as a modifier on an inner class because there is currently no such thing as a ` static ` class in PHP.
209-
210- #### Visibility
211-
212- A ` private ` or ` protected ` inner class type is only accessible within the class it is defined in
213- (or its subclasses in the case of protected classes).
214- This is similar to C#, so you may return a private type from a public method,
215- but not use it as a type hint from outside the outer class:
216-
217- ``` php
218- class Outer {
219- private class PrivateInner(string $message);
220-
221- public function getInner(): self::PrivateInner {
222- return new self::PrivateInner('Hello, world!');
223- }
224- }
225-
226- // using a private inner class from outside the outer class, as a type hint is forbidden
227- function doSomething(Outer::PrivateInner $inner) {
228- echo $inner->message;
229- }
230-
231- // this is ok:
232- $inner = new Outer()->getInner();
233-
234- // but this is not:
235- doSomething($inner);
236- // Fatal error: Private inner class Outer::Inner cannot be used in the global scope
237- ```
238-
239- Just like with other languages that support inner classes,
240- it is better to return an interface or a base class from a method instead of exposing a private/protected class.
241-
242- You may also not instantiate a private/protected class from outside the outer class’s scope:
243-
244- ``` php
245- $x = new Outer::PrivateInner();
246- // Fatal error: Uncaught Error: Cannot access private inner class Outer::Inner
247- ```
248-
249- #### Inheritance
250-
251- Classes may not inherit from inner classes. Inner classes may inherit from other classes, including the outer class.
240+ However, no classes may not inherit from inner classes,
241+ but inner classes may inherit from other classes, including the outer class.
252242
253243#### Names
254244
0 commit comments