PHP 8.4 New Features: Enhanced Performance and Developer Experience
Explore the latest features and improvements in PHP 8.4, including performance optimizations, new language capabilities, and developer-friendly enhancements that make PHP development more efficient and enjoyable.
New features of PHP 8.4
The official release of PHP 8.4 is scheduled for next week, November 21, 2024.
Prior to this release, a series of pre-release versions (Alpha, Beta, and candidate versions) allowed the community to test new features and make last-minute adjustments. PHP 8.4 introduces multiple improvements, including new features for manipulating arrays, property hooks inspired by other languages, and simplified syntax. Let's review the new features to remember in this version together.
Property Hooks
Property Hooks is one of the main features introduced in version 8.4. The inspiration for PHP implementation comes from existing implementations in other languages such as Kotlin, C#, Swift, Javascript, or Python. Let's give a few examples to illustrate the purpose of Property Hooks and how to use them:
<?php
declare(strict_types=1);
class Foo
{
private string $id;
public function getId(): string
{
return $this->id;
}
public function setId(string $id): void
{
$this->id = $id;
}
}
Starting from PHP 8, due to Constructor Property Promotion
it can be simplified in the following ways:
<?php
class Foo {
function __construct(public string $id) {}
}
We must keep the visitor (getter/setter
) in this case, we will consider rich models that include business logic, but we lose the advantage of lighter syntax. PHP version 8.4 introduced Property Hooks
to fix this issue:
<?php
class Foo {
public function __construct(
public string $id {
get {
return '#' . $this->id;
}
set(string $id) {
$this->id = mb_strtoupper($id);
}
},
) {}
}
At first glance, grammar may seem confusing, but like any grammar evolution, you will get used to it over time.
Another possibility introduced by Property Hooks is the ability to define interfaces on properties.
With this new version of PHP, we can write the following definition:
<?php
interface HasId {
public string $id { get; set; }
}
// Arrow functions can be used to shorten the syntax
class Foo implements HasId {
function __construct(
public string $id {
get => '#' . $this->id;
set(string $id) => $this->id = mb_strtoupper($id);
},
) {}
}
// The interface contract is also respected without using Property Hooks by declaring the property public
class Bar implements HasId {
function __construct(public string $id) {}
}
A complete case study:
<?php
declare(strict_types=1);
interface HasId {
public string $id { get; set; }
}
class Foo implements HasId {
function __construct(
public string $id {
get => '#' . $this->id;
set(string $id) => $this->id = mb_strtoupper($id);
},
) {}
}
class Bar implements HasId {
function __construct(public string $id) {}
}
class Baz {
public function display(HasId $object): void
{
echo $object->id . PHP_EOL;
}
public function update(HasId $object, string $id): void {
$object->id = $id;
$this->display($object);
}
}
$foo = new Foo(id: 'FOO');
$bar = new Bar(id: 'BAR');
$baz = new Baz();
$baz->display($foo);
$baz->update($foo, 'foo');
$baz->display($bar);
$baz->update($bar, 'bar');
Set the visibility of class attributes with asymmetric visibility
Asymmetric visibility allows you to set different visibility for the same attribute based on whether the relevant operation is reading or writing the attribute. Then, public visibility for read access and more restricted visibility (protected or private) for write access can be defined. The next two classes are equivalent, and with the introduction of asymmetric visibility, the syntax becomes more concise.
<?php
class Foo {
function __construct(
private string $id,
) {}
public function getId(): string {
return $this->id;
}
}
class Bar {
function __construct(
public private(set) string $id,
) {}
}
Asymmetric visibility comes with some rules that are easy to understand:
- Attributes must be typed (constraint from PHP implementation)
- Only focusing on object properties, static properties cannot benefit from it (this is also a constraint generated by PHP implementation)
- For object properties, if the property is set to private(set), linked objects cannot be modified within a scope different from the current class. However, if the properties of the linked object are defined as Properties, they can be modified
- For array type properties, if the property is set to private(set), the array cannot be manipulated outside the scope of the current class (adding elements, deleting elements, etc.)
- The visibility of set cannot be wider than that of get
- For class inheritance or interface contracts, visibility cannot be stricter, but can be broader
The differences between readonly
properties (introduced in PHP 8.1) and public private(set)
attributes are very small, but worth mentioning. The asymmetric visibility defined above will have the same effect, except that it allows for internal changes. In other words, readonly
restricts mutation
and also has a unique write effect during instantiation.
The management operates independently of the Property Hook, but these two mechanisms can be used in combination. Examples of these two functions are provided here.
Native support for lazy objects
Lazy objects are objects whose actual instantiation will be postponed until the actual required time (as their instantiation is usually expensive). For performance reasons, they are widely used in Doctrine and Symfony.
Martin Fowler established four possible implementations in his theoretical definition. Two of them are implementations that do not require modifying existing objects: Ghost and Proxy. These are preserved and accessed by adding methods in the PHP Reflection API.
In both cases, an initialization function will be created. For Ghosts, this function will directly apply to the object. For Proxy, it is a function that initializes a lazy object and then feeds back the interaction to the real instance.
In both cases, the instantiation mechanism is triggered by accessing the state of the real object: reading or writing properties, testing whether properties have values, cloning, etc. This behavior can be disabled for specific properties through specific functions, and in some cases, it can be defined or parameterized, such as for debugging or serialization.
As it is reserved for very limited and abstract use cases by definition, we invite you to read the RFC to discover code examples and detailed functionality for two different implementations.
Class instantiation without parentheses
More interestingly, this evolution reduces the burden of syntax by making parentheses redundant when instantiating new objects.
<?php
// Before and still valid
$o = (new Operation(0))->add(10)->multiply(2);
// Since PHP 8.4
$o = new Operation(0)->add(10)->multiply(2);
Analyzing HTML5
Created a new DOM\HTMLDocument
class to allow HTML5 parsing, in order to ensure compatibility with HTML4
. The backward compatibility of the current class will remain unchanged. These two classes maintain the same API, so they can be used in the same way. Only the construction logic has been changed and requires the use of one of the available factories. The underlying libraries for C language writing are Lexbor
.
New functions
Four new functions have been added to the array, which complement the existing functions.
array_find
array_find
returns the first match of the callback function:
<?php
$array = ['A', 'AA', 'AAA'];
$arrayWithKeys = ['A' => 1, 'AA' => 2, 'AAA' => 3];
array_find($array, static fn(string $value): bool => strlen($value) > 2); // returns AAA
array_find($array, static fn(string $value): bool => strlen($value) > 3); // returns null
array_find($arrayWithKeys, static fn(int $value, string $key): bool => $value === strlen($key)); // returns 1
array_find_key
array_find_key
works the same way as the previous function, but returns a key instead of a value:
<?php
$array = ['A', 'AA', 'AAA'];
$arrayWithKeys = ['A' => 1, 'AA' => 2, 'AAA' => 3];
array_find_key($array, static fn(string $value): bool => strlen($value) > 2); // returns 2
array_find_key($array, static fn(string $value): bool => strlen($value) > 3); // returns null
array_find_key($arrayWithKeys, static fn(int $value, string $key): bool => $value === strlen($key)); // returns A
array_any
If at least one element in the array matches the callback function, array_any
returns true
:
<?php
$array = ['A', 'AA', 'AAA'];
$arrayWithKeys = ['A' => 1, 'AA' => 2, 'AAA' => 3];
array_any($array, static fn(string $value): bool => strlen($value) > 2); // returns true
array_any($arrayWithKeys, static fn(int $value, string $key): bool => $value === strlen($key)); // returns true
array_all
If all elements in the array match the callback function, array_all
returns true
:
<?php
$array = ['A', 'AA', 'AAA'];
$arrayWithKeys = ['A' => 1, 'AA' => 2, 'AAA' => 3];
array_all($array, static fn(string $value): bool => strlen($value) < 4); // returns true
array_all($arrayWithKeys, static fn(int $value, string $key): bool => $value === strlen($key)); // returns true
Improvement and bug fixes
Among other things, we have retained the following changes:
- Added new multi-byte functions to manipulate strings:
mb_trim
,mb_ltrim
,mb_rtrim
,mb_ucfirst
,mb_lcfirst
- Added new functions for creating
DateTime
objects from timestamps exit
anddie
elements lost their status and were replaced by special functions. Without compromising backward compatibility, this allows for similar operations to be performed on functions, such as typing input parameters more accurately- The following extensions are being removed from the core to join PECL:
Pspel
,IMAP
,OCI8
, andPDO-OCI
- Added four new rounding modes for rounding function
- Two new encryption algorithms have been added to Sodium and upgraded
OpenSSL
- Added a new option for cURL
Complete update log: PHP 8.4 Changelog
Related Posts
GitHub Daily Recommendation 2025-01-23
🚀 GitHub Daily Recommendations Alert! 🌟 Dive into today's top open-source treasures, from cutting-edge AI tools to essential Web Frontend Development resources. 🌐✨ Don't miss out on the latest in Cloud Computing, Data Analysis, and more! 📊🔧 #OpenSourceProjects #Featured
Product Hunt Daily Recommendation 2025-01-23
Discover the latest Product Hunt daily picks for today's top innovations! Dive into hand-picked AI tools, SaaS products, and mobile apps. Explore, learn, and be the first to try out the newest tech trends. 🚀 #ProductHunt #DailyInnovations #TechTrends
GitHub Daily Recommendation 2025-01-21
🚀 GitHub Daily Recommendations Alert! 🌟 Dive into today's top-notch open-source projects, from cutting-edge AI tools to essential Web Frontend Development resources. 🌐 Enhance your coding skills and discover the best of open-source innovation right here! 📚✨