PHP 8.4 was released in November 2024. Everything on this page needs PHP 8.4 or newer, so these examples cannot run on older versions (and not on this course’s local test server, which runs PHP 8.2). The code follows the official release notes at php.net/releases/8.4.
Property hooks
Property hooks let a property define its own get and set behaviour, so you often do not need separate getter and setter methods.
<?php
class Locale
{
public string $languageCode;
public string $countryCode
{
set (string $countryCode) {
$this->countryCode = strtoupper($countryCode);
}
}
public string $combinedCode
{
get => sprintf("%s_%s", $this->languageCode, $this->countryCode);
set (string $value) {
[$this->languageCode, $this->countryCode] = explode("_", $value, 2);
}
}
public function __construct(string $languageCode, string $countryCode)
{
$this->languageCode = $languageCode;
$this->countryCode = $countryCode;
}
}
$locale = new Locale("en", "us");
echo $locale->combinedCode; // en_US
- A
sethook runs when the property is assigned. It can clean or check the value. - A
gethook runs when the property is read. It can calculate the value. - A property with only a
gethook that does not use a stored value is a virtual property.
Asymmetric visibility
Control reading and writing separately: public to read, private (or protected) to write.
<?php
class PhpVersion
{
public private(set) string $version = "8.4";
public function increment(): void
{
[$major, $minor] = explode(".", $this->version);
$minor++;
$this->version = "{$major}.{$minor}";
}
}
$v = new PhpVersion();
echo $v->version; // readable from anywhere
// $v->version = "9"; // Error: cannot modify from outside
This removes a lot of “private property plus public getter” code.
new without extra parentheses
<?php
class PhpVersion
{
public function getVersion(): string
{
return "PHP 8.4";
}
}
echo new PhpVersion()->getVersion(); // no (new PhpVersion())-> needed
New array functions
array_find(), array_find_key(), array_any() and array_all() answer common questions without building a new array.
<?php
$animal = array_find(
["dog", "cat", "cow", "duck", "goose"],
static fn(string $value): bool => str_starts_with($value, "c"),
);
var_dump($animal); // string(3) "cat"
A fallback for older versions:
<?php
function findFirst(array $items, callable $test): mixed
{
foreach ($items as $item) {
if ($test($item)) {
return $item;
}
}
return null;
}
var_dump(findFirst(["dog", "cat", "cow"], fn($v) => str_starts_with($v, "c")));
string(3) "cat"
The #[\Deprecated] attribute
Marks your own functions, methods and class constants as deprecated, with a message. PHP then raises a deprecation notice when someone uses them.
<?php
class Report
{
#[\Deprecated(message: "use Report::build() instead", since: "8.4")]
public function make(): string
{
return $this->build();
}
public function build(): string
{
return "report";
}
}
Other additions
- Lazy objects: create an object whose initialisation runs only when it is first used. Mostly for frameworks.
- HTML5 DOM: new
Dom\HTMLDocumentclasses that parse HTML5 correctly, withquerySelector(). mb_trim(),mb_ltrim(),mb_rtrim(),mb_ucfirst(),mb_lcfirst()for multibyte strings.- Object API for BCMath:
BcMath\Numberwith operators. request_parse_body()to read PUT and PATCH bodies.DateTime::createFromTimestamp(),RoundingModeenum forround().
Deprecation to know
Declaring a parameter as Type $x = null (an implicit nullable type) is deprecated in 8.4. Write ?Type $x = null.
Should you use it?
If your host supports PHP 8.4, these are pleasant additions. If your code must also run on 8.3 or older, avoid them.