Exploring New Features and Changes in PHP 8.4

Published:

PHP 8.4 introduces groundbreaking features that streamline coding processes and enhance performance. From Property Hooks to Asymmetric Property Visibility, this release has a lot to offer developers.

PHP 8.4 featuresPHP 8.4 features

Key Features in PHP 8.4

1. Property Hooks

PHP 8.3 and earlier: Property access and modification required boilerplate code with getters and setters.

class User {
    private string $firstName;
    private string $lastName;

    public function getFullName(): string {
        return "$this->firstName $this->lastName";
    }

    public function setFullName(string $fullName): void {
        [$this->firstName, $this->lastName] = explode(' ', $fullName, 2);
    }
}

PHP 8.4: Property Hooks simplify this process.

class User {
    public string $firstName;
    public string $lastName;

    public string $fullName {
        get => "{$this->firstName} {$this->lastName}"; // Getter
        set => [$this->firstName, $this->lastName] = explode(' ', $value, 2); // Setter
    }
}

$user = new User();
$user->fullName = 'Open Swoole';
echo $user->fullName; // Outputs: Open Swoole

2. Asymmetric Property Visibility

PHP 8.3 and earlier: Visibility for properties was uniform for both read and write operations.

class Config {
    private string $version = '1.0.0';

    public function getVersion(): string {
        return $this->version;
    }

    public function setVersion(string $version): void {
        $this->version = $version;
    }
}

PHP 8.4: You can now specify different visibility levels for reading and writing properties.

class Config {
    public private(set) string $version = '1.0.0';

    public function updateVersion(string $newVersion): void {
        $this->version = $newVersion;
    }
}

$config = new Config();
echo $config->version; // Outputs: 1.0.0
$config->updateVersion('1.1.0');
echo $config->version; // Outputs: 1.1.0

3. New Array Functions

PHP 8.3 and earlier: Finding or validating array elements required custom loops or array functions.

$numbers = [1, 2, 3, 4, 5];
$firstEven = null;
foreach ($numbers as $n) {
    if ($n % 2 === 0) {
        $firstEven = $n;
        break;
    }
}
echo $firstEven; // Outputs: 2

PHP 8.4: Simplified array operations with new functions like array_find and array_any.

$numbers = [1, 2, 3, 4, 5];

$firstEven = array_find($numbers, fn($n) => $n % 2 === 0);
echo $firstEven; // Outputs: 2

$hasNegative = array_any($numbers, fn($n) => $n < 0);
var_dump($hasNegative); // Outputs: bool(false)

4. Simplified Object Instantiation

PHP 8.3 and earlier: Method chaining after instantiation required wrapping the object in parentheses.

$result = (new Calculator())->add(5, 3)->getResult();

PHP 8.4: Directly chain method calls and property access.

$result = new Calculator()->add(5, 3)->getResult();

5. HTML5 Support in DOM Extension

PHP 8.3 and earlier: Limited support for HTML5 parsing and serialization in the DOM extension.

$dom = new DOMDocument();

$html = '<!DOCTYPE html><html><body><p>Open Swoole News and Tutorial</p></body></html>';
$doc = $doc->loadHTML($html);
echo $doc->saveHTML();

$node = (new DOMXPath($dom))->query("//body/p")[0];

PHP 8.4: Full HTML5 support for easier web development.

use DOM\HTMLDocument;

$html = '<!DOCTYPE html><html><body><p>Open Swoole News and Tutorial</p></body></html>';
$doc = HTMLDocument::createFromString($html);
echo $doc->saveHTML();

$node = $doc->querySelector('body > p');

6. Object-Oriented BCMath API

PHP 8.3 and earlier: BCMath functions were procedural.

$sum = bcadd('1.5', '2.5');
echo $sum; // Outputs: 4.0

PHP 8.4: BCMath gains an object-oriented API.

use BCMath\Number;

$num1 = new Number('1.5');
$num2 = new Number('2.5');
$sum = $num1 + $num2;
echo $sum; // Outputs: 4.0

7. #[Deprecated] Attribute

PHP 8.3 and earlier: Deprecations were documented but not explicitly marked in code.

function oldFunction() {
    trigger_error('Use newFunction() instead', E_USER_DEPRECATED);
    // ...
}

PHP 8.4: Use the #[Deprecated] attribute.

#[\Deprecated("Use newFunction() instead", since: "8.4")]
function oldFunction() {
    // ...
}

8. Lazy Objects

PHP 8.3 and earlier: Initialization of objects occurred immediately upon creation.

PHP 8.4: Lazy objects delay initialization until first use.

class Foo {
    public function __construct(private string $data) {
        // Some operation
    }
}

$initializer = fn() => new Foo('some data');
$reflector = new ReflectionClass(Foo::class);
$object = $reflector->newLazyGhost($initializer);

9. Enhanced Multibyte String Functions

PHP 8.3 and earlier: String trimming functions were not multibyte-safe.

$text = " こんにちは ";
$trimmed = trim($text);
echo $trimmed; // Outputs incorrect results for multibyte strings

PHP 8.4: New functions like mb_trim provide multibyte-safe trimming.

$text = " こんにちは ";
$trimmed = mb_trim($text);
echo $trimmed; // Outputs: こんにちは

10. Enhanced DateTime Methods

PHP 8.3 and earlier: Creating DateTime objects from timestamps required custom logic.

$timestamp = 1987654321;
$date = (new DateTime())->setTimestamp($timestamp);
echo $date->format('Y-m-d H:i:s');

PHP 8.4: New DateTime::createFromTimestamp(), DateTime::getMicrosecond(), DateTime::setMicrosecond(), DateTimeImmutable::createFromTimestamp(), DateTimeImmutable::getMicrosecond(), and DateTimeImmutable::setMicrosecond() methods.

$timestamp = 1987654321;
$date = DateTimeImmutable::createFromTimestamp($timestamp);
echo $date->format('Y-m-d H:i:s');