With the release of PHP8.4 I tried experimenting with the features it provides. One such feature is support for properties in interfaces. Interfaces were getting a few improvements over time, but up to PHP8.3 only methods were allowed, omitting properties from the definition.
Wanting to utilize this new feature I went on and created an interface with a property, expecting everything to go smoothly:
<?php
interface MyInterface
{
public string $property;
}
To my surprise, the result was an error instead:
PHP Fatal error: Interfaces may only include hooked properties
Searching around, it took me some time to figure out what was wrong.
Hooked properties
The properties on interfaces are really available now but with a small quirk. Feature requires a new language syntax:
<?php
interface MyInterface
{
public string $readWriteProperty { get; set; }
public string $readOnlyProperty { get; }
public string $writeOnlyProperty { set; }
}
It is required to explicitly state if the property is read-only via
{ get; }
, write-only via { set; }
, or, what was the most troublesome
for me to find and answer for, and also what I was actually looking for, if
the property is read-write via { get; set; }
.
At the time of writing, I feel a bit ashamed, because the official PHP docs on the topic have the syntax clearly outlined, but somehow I have missed it.
Foreword
To me, it still feels quire weird that the statement containing property
hooks does not need to end with a semicolon ;
but as a side note, we
already had a few new constructs since PHP8.0 in the language, for instance
in the form of match
expression:
<?php
$animal = 'dog';
$value = match ($animal) {
'cat' => 'This animal is a cat',
'dog' => 'This animal is a dog',
'mouse' => 'This animal is a mouse',
};
The semicolon in the above example actually is at the end of a statement, but right after curly brace. Such syntax was not in the language in PHP7.4 or lower, at least to my knowledge. Also, more new changes and features are coming steadily, which a s great thing for PHP world.
Hopefully, when you land here by searching for an error, you will now know hot to proceed. If not, here is probably what you are looking for:
interface MyInterface
{
- public string $property;
+ public string $property { get; set; }
}
Enjoy!
Links
- https://laravel-news.com/php-8-4-0#content-php-property-hooks
- https://laravel-news.com/php-property-hooks
- https://stitcher.io/blog/new-in-php-84#property-hooks-rfc
- https://www.php.net/manual/en/control-structures.match.php
- https://www.php.net/manual/en/language.oop5.interfaces.php#language.oop5.interfaces.properties
- https://ashallendesign.co.uk/blog/php-84-property-hooks#content-read-only-hooked-properties