What's New in PHP 8.4: A Comprehensive Guide
PHP 8.4, scheduled for release on November 21, 2024, brings several groundbreaking features that significantly enhance developer productivity and code clarity. Let's dive deep into the major changes and understand how they'll transform PHP development.
Property Hooks: A Revolution in Property Management
One of the most significant additions in PHP's history is the introduction of property hooks. This feature fundamentally changes how we handle class properties by eliminating verbose getter and setter boilerplate code.
Consider this common scenario in pre-8.4 PHP:
class BookViewModel
{
private array $authors = [];
public function getCredits(): string
{
return implode(', ', array_map(
fn (Author $author) => $author->name,
$this->authors
));
}
public function setMainAuthor(Author $author): void
{
$this->authors[] = $author;
$this->mainAuthor = $author;
}
}
With PHP 8.4's property hooks, this becomes much more elegant:
class BookViewModel
{
public function __construct(
private array $authors,
) {}
public string $credits {
get {
return implode(', ', array_map(
fn (Author $author) => $author->name,
$this->authors,
));
}
}
public Author $mainAuthor {
set (Author $mainAuthor) {
$this->authors[] = $mainAuthor;
$this->mainAuthor = $mainAuthor;
}
get => $this->mainAuthor;
}
}
Property hooks offer several advantages:
- Virtual properties through get-only hooks
- Computed properties without method calls
- Interface support for property definitions
- Clear separation of concerns
Asymmetric Visibility: Fine-grained Access Control
PHP 8.4 introduces asymmetric visibility, allowing different access levels for reading and writing properties. This feature is particularly valuable for creating immutable objects and enforcing encapsulation.
class BookViewModel
{
// Public read, private write
private(set) Author $author;
// Public read, protected write
public protected(set) Author $editor;
// Works with constructor promotion too
public function __construct(
private(set) Author $publisher
) {}
}
This feature elegantly solves the common pattern of "read-only from outside, writable from inside" without requiring separate getters and setters.
Simplified Method Chaining
PHP 8.4 removes a long-standing annoyance by allowing method chaining on new instances without extra parentheses. This seemingly small change makes code more readable and reduces syntax noise.
// Before PHP 8.4
$name = (new ReflectionClass($objectOrClass))->getShortName();
// PHP 8.4
$name = new ReflectionClass($objectOrClass)->getShortName();
This improvement applies to all forms of member access:
- Method calls
- Property access
- Static method calls
- Constant access
Enhanced Array Functions
PHP 8.4 introduces several useful array functions that developers have long relied on third-party libraries to provide:
// Find first matching element
$longTitle = array_find(
$posts,
fn (Post $post) => strlen($post->title) > 50
);
// Check if any element matches
$hasPublished = array_any(
$posts,
fn (Post $post) => $post->isPublished()
);
// Check if all elements match
$allPublished = array_all(
$posts,
fn (Post $post) => $post->isPublished()
);
Modern HTML5 Support
The new \Dom\HTMLDocument
class brings proper HTML5 parsing capabilities to PHP:
$doc = \Dom\HTMLDocument::createFromString($contents);
// Now properly handles modern HTML5 elements and syntax
This addition maintains backward compatibility while providing modern HTML processing capabilities.
BCMath Object API
PHP 8.4 introduces an object-oriented interface for BCMath operations with operator overloading support:
use BCMath\Number;
$price = new Number('19.99');
$quantity = new Number('2');
$total = $price * $quantity;
echo $total->value; // '39.98'
Improved Deprecation Handling
The new #[Deprecated]
attribute provides a standardized way to mark code as deprecated:
#[Deprecated(
"Use newFunction() instead",
since: "tempest/framework:1.1"
)]
function oldFunction() {
// ...
}
Other Notable Improvements
DateTime Enhancements
// New static constructors
$date = DateTime::createFromTimestamp(1234567890);
// Microsecond precision
$date->setMicrosecond(123456);
$microseconds = $date->getMicrosecond();
Lazy Objects
$initializer = static function (MyClass $proxy): MyClass {
return new MyClass(123);
};
$object = (new ReflectionClass(MyClass::class))->newLazyProxy($initializer);
JIT Improvements
# New JIT configuration
opcache.jit=disable
opcache.jit_buffer_size=64m
Breaking Changes and Deprecations
Several backwards-incompatible changes are introduced:
- E_STRICT constant deprecation
- Implicit nullable types removal
- GMP class now final
- Various DOM element property deprecations
- Session configuration changes
Preparing for the Update
To ensure a smooth transition to PHP 8.4:
- Update nullable type hints to use explicit notation
- Review usage of deprecated DOM properties
- Update JIT configurations if using custom settings
- Test thoroughly with the new property hooks system
- Consider adopting asymmetric visibility for better encapsulation
PHP 8.4 represents a significant step forward in PHP's evolution, introducing features that make code more expressive and maintainable while removing long-standing pain points. The additions of property hooks and asymmetric visibility in particular show PHP's continued commitment to modern programming paradigms while maintaining its pragmatic approach to web development.