@@ -199,6 +199,72 @@ class Example
199
199
On a backed property, omitting a <literal >get</literal > or<literal >set</literal >
200
200
hook means the default read or write behavior will be used.
201
201
</simpara >
202
+ <note >
203
+ <simpara >
204
+ Hooks can be defined when using
205
+ <link linkend =" language.oop5.decon.constructor.promotion" >constructor property promotion</link >.
206
+ However, when doing so, values provided
207
+ to the constructor must match the type associated with the property,
208
+ regardless of what the <literal >set</literal > hook might allow.
209
+ </simpara >
210
+ <simpara >
211
+ Consider the following:
212
+ </simpara >
213
+ <programlisting role =" php" >
214
+ <![CDATA[
215
+ class Example
216
+ {
217
+ public function __construct(
218
+ public private(set) DateTimeInterface $created {
219
+ set (string|DateTimeInterface $value) {
220
+ if (is_string($value)) {
221
+ $value = new DateTimeImmutable($value);
222
+ }
223
+ $this->created = $value;
224
+ }
225
+ },
226
+ ) {
227
+ }
228
+ }
229
+ ]]>
230
+ </programlisting >
231
+ <simpara >
232
+ Internally, the engine decomposes this to the following:
233
+ </simpara >
234
+ <programlisting role =" php" >
235
+ <![CDATA[
236
+ class Example
237
+ {
238
+ public private(set) DateTimeInterface $created {
239
+ set (string|DateTimeInterface $value) {
240
+ if (is_string($value)) {
241
+ $value = new DateTimeImmutable($value);
242
+ }
243
+ $this->created = $value;
244
+ }
245
+ }
246
+
247
+ public function __construct(
248
+ DateTimeInterface $created,
249
+ ) {
250
+ $this->created = $created;
251
+ }
252
+ }
253
+ ]]>
254
+ </programlisting >
255
+ <simpara >
256
+ Any attempts to set the property outside the constructor will
257
+ allow either <type >string</type > or <interfacename >DateTimeInterface</interfacename >
258
+ values, but the constructor will only allow <interfacename >DateTimeInterface</interfacename >.
259
+ This is because the defined type for the property (<interfacename >DateTimeInterface</interfacename >)
260
+ is used as the parameter type within the constructor signature, regardless of what
261
+ the <literal >set</literal > hook allows.
262
+ </simpara >
263
+ <simpara >
264
+ If this kind of behavior is needed from the constructor, constructor
265
+ property promotion cannot be used.
266
+ </simpara >
267
+ </note >
202
268
</sect2 >
203
269
<sect2 xml : id =" language.oop5.property-hooks.virtual" >
204
270
<title >Virtual properties</title >
0 commit comments