Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds a note about hooks + constructor property promotion #4264

Merged
merged 6 commits into from
Dec 13, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions language/oop5/property-hooks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,72 @@ class Example
On a backed property, omitting a <literal>get</literal> or<literal>set</literal>
hook means the default read or write behavior will be used.
</simpara>
<note>
<simpara>
Hooks can be defined when using
<link linkend="language.oop5.decon.constructor.promotion">constructor property promotion</link>.
However, when doing so, values provided
to the constructor must match the type associated with the property,
regardless of what the <literal>set</literal> hook might allow.
</simpara>
<simpara>
Consider the following:
</simpara>
<programlisting role="php">
<![CDATA[
class Example
{
public function __construct(
public private(set) DateTimeInterface $created {
set (string|DateTimeInterface $value) {
if (is_string($value)) {
$value = new DateTimeImmutable($value);
}
$this->created = $value;
}
},
) {
}
}
]]>
</programlisting>
<simpara>
Internally, the engine decomposes this to the following:
</simpara>
<programlisting role="php">
<![CDATA[
class Example
{
public private(set) DateTimeInterface $created {
set (string|DateTimeInterface $value) {
if (is_string($value)) {
$value = new DateTimeImmutable($value);
}
$this->created = $value;
}
}

public function __construct(
DateTimeInterface $created,
) {
$this->created = $created;
}
}
]]>
</programlisting>
<simpara>
Any attempts to set the property outside the constructor will
allow either <type>string</type> or <interfacename>DateTimeInterface</interfacename>
values, but the constructor will only allow <interfacename>DateTimeInterface</interfacename>.
This is because the defined type for the property (<interfacename>DateTimeInterface</interfacename>)
is used as the parameter type within the constructor signature, regardless of what
the <literal>set</literal> hook allows.
</simpara>
<simpara>
If this kind of behavior is needed from the constructor, constructor
property promotion cannot be used.
</simpara>
</note>
</sect2>
<sect2 xml:id="language.oop5.property-hooks.virtual">
<title>Virtual properties</title>
Expand Down
Loading