What's New in PHP 8.4: Features You'll Actually Use
PHP 8.4 may not be a headline-grabber, but it introduces several developer-friendly features that can streamline your day-to-day work. Whether you're building in Laravel or working on a core PHP project, there's something here for you.
From improved object behavior to cleaner syntax, here's a breakdown of the most practical features — along with deprecations to prepare for.
- Property Hooks. Native getter and setter behavior right inside property definitions.
- Asymmetric Property Visibility. Use different visibilities for reading and writing a property.
- New array_*() functions array_find(), array_find_key(), array_any(), and array_all().
1. Property Hooks
PHP 8.4 introduces property hooks, letting you define behavior for getting or setting properties.
class Car
{
public function __construct(
private string $make,
private string $model
) {}
public string $fullDetails {
get => $this->make . " - " . $this->model;
set {
[$this->make, $this->model] = explode(' ', $value, 2);
}
}
}
2. Asymmetric Property Visibility
Now you can expose a property publicly for reading but restrict writing.
class Product
{
// Public getter, private setter
public string $name {
get;
private set;
}
// Private getter, public setter
public float $price {
private get;
public set;
}
public function __construct(string $name, float $price)
{
$this->name = $name; // Allowed (inside the class)
$this->price = $price; // Allowed (inside the class)
}
public function showInfo(): void
{
echo "Product: {$this->name}, Price: {$this->price}\n"; // Allowed (inside the class)
}
}
$product = new Product("Lego Set", 19.99);
// Readable because $name has a public getter
echo $product->name . "\n"; // Allowed
// Not allowed: $name has a private setter
// $product->name = "New Name"; // Fatal error
// Writable because $price has a public setter
$product->price = 24.99; // Allowed
// Not allowed: $price has a private getter
// echo $product->price; // Fatal error
3. array_find()
New array_*() functions array_find(), array_find_key(), array_any(), and array_all() are now available.
$animal = array_find(
['dog', 'cat', 'cow', 'duck', 'goose'],
static fn (string $value): bool => str_starts_with($value, 'c'),
);
var_dump($animal); // string(3) "cat"
No need for unsightly loops now!
4. BCMath OOP Support
The BCMath extension now has a proper object API.
use BCMath\Number;
$num = new Number('1.23');
$num2 = new Number('2.111');
// If scale is omitted, the larger scale of $num and $num2 is used.
// In this example, the scale of $num2 is larger, so the calculation is done with scale = 3.
$result = $num->add($num2); // value is '3.341', scale is 3.
$num = new Number('1.23');
$num2 = new Number('2.111');
$result = $num->add($num2, 10); // value is '3.3410000000', scale is 10.
$num = new Number('1.23');
$num2 = new Number('2.111');
$result = $num->add($num2, 1, PHP_ROUND_AWAY_FROM_ZERO); // value is '3.4', scale is 1.
Deprecated in PHP 8.4
Here are a few things being deprecated that you'll want to catch early:
- mysqli_ping(), mysqli_kill(), mysqli_refresh() - Migrate to PDO where possible.
- exit() behavioral change - The exit() (and die()) language constructs now behave more like regular functions. As a result, they can be used as callables, are influenced by the strict_types declaration, and perform standard type coercion rather than converting any non-integer value to a string. Consequently, passing invalid types to exit() or die() will now consistently throw a TypeError.
Conclusion
PHP 8.4 makes writing modern, expressive code that bit easier. If you’re developing Laravel packages or building applications from scratch, the new features will improve your developer experience with minimal fuss. Just remember to test for deprecated functions in older projects before upgrading.