ArticlesNews & Events

PHP 8.4 New Features, Improvements and Deprecations

PHP 8.4

PHP 8.4 released on November 21, 2024, with this release there will be new features, improvements, deprecation’s and more.

 

 

Let’s check the new features added on PHP 8.4

New Features

  • New array_find functions

PHP 8.4 comes with new array functions array_find() and their counterparts array_find_key(), array_any(), array_all(). array_find() retrieves the first matching element that fulfills the callback condition. You can think of it like Javascript Array.find method. 

$posts = [
    [
        'id' => 1,
        'title' => 'Post 1'
    ],
    [
        'id' => 2,
        'title' => 'Post 2'
    ],
    [
        'id' => 3,
        'title' => 'Post 3'
    ]
];

$findPost = array_find($posts, fn($post) => $post['id'] === 2);

echo $findPost['title'];     // Post 2

All array_find() functions accepts the target array and a callback. If the callback returns “true” at any point, it will stop searching and return immediately.

array_find_key() returns the key of the first element for which the $callback returns true. If no matching element is found the function returns NULL.

$findIndex = array_find_key($posts, fn($post) => $post['id'] === 3);

echo $findIndex; // 2

array_any() and array_all() return a boolean instead of a value.

array_any() return true if at least one element within the array matches a callback’s condition,

$numbers = [1, 3, 10, 14, 20];

$isThereNumberGreaterTen = array_any($numbers, fn($num) => $num > 10);

var_dump($isThereNumberGreaterTen);    
// bool(true)

while the array_all() function return true if all elements matches a callback’s condition.

$isAllNumbersGreaterTen = array_all($numbers, fn($num) => $num > 10);

var_dump($isAllNumbersGreaterTen); 

// bool(false) 

 

  • New Multibyte String Functions

In PHP 8.4 new multibyte string functions added for functions like trim(), ltrim() and rtrim(), etc. Now there are are mb_trim(), mb_ltrim(), mb_rtrim(), mb_ucfirst(), mb_lcfirst().

 

  • new without parenthesis

PHP 8.4 provides a short syntax for accessing methods and properties when using the new keyword. Prior to PHP 8.4 in order to invoke a class method directly, you have to wrap the new keyword within parenthesis:

PHP < 8.4

class Post
{
    private string $title = "";

    public function setTitle(string $title)
    {
        $this->title = $title;

        return $this;
    }

    public function getTitle()
    {
        return $this->title;
    }
}

$post = (new Post())->setTitle("Post title");    // Parenthesis required

With PHP 8.4

$post = new Post()->setTitle("Post title");

With this feature method chaining becomes short:

$post = new Post()->setTitle("Post title")
          ->getTitle();

echo $post

You can also access properties and constants the same way:

class Foobar 
{
    const SUBJECT = "subject";
    public $title = "sample title";
    public static $admin = "admin";
}

new Foobar()::SUBJECT;       // subject
new Foobar()->title;         // sample title
new Foobar()::$admin;        // admin

 

  •  Property Hooks

Another nice feature comes with PHP 8.4 is the Property Hooks inspired from C# or Kotlin. Previously when we need to set and retrieve properties we tend to declare a custom getter and setter methods for that property, or using the PHP magic methods __set() and __get().  

Consider the previous Post class:

class Post
{
    private string $title = "";

    public function setTitle(string $title)
    {
        $this->title = $title;

        return $this;
    }

    public function getTitle()
    {
        return $this->title;
    }
}

Now with PHP 8.4 we can utilize the Property Hooks syntax and redefine the getters and setters for $title like so:

class Post
{
    public string $title {

        get => $this->title;

        set {
            $this->title = $value;
        }
    }
}

Then we can set and get the property using class instance:

$post = new Post();

$post->title = "sample post";

echo $post->title;   // sample post

As you see the terminology for a property hook:

<visibility modifier> <type> <$property> {
   get {}

   set() {}
}

Most notably you don’t have to define get() and set() hooks altogether, you can define any of them:

class Post
{
    public string $title {
        set {
            $this->title = $value;
        }
    }
}

 

  • Asymmetric Visibility

Prior to PHP 8.4 when declaring class properties with visibility, this visibility applies on both read and write operations:

class Post
{
    public string $title = "";

    public function __construct(string $title)
    {
        $this->title = $title;
    }
}

Because the $title property is made public, user can set and read it from outside the class:

$post = new Post("post title");            
 
$post->title = "updated post title";        

echo $post->title;

In this code the user can set the property directly using $post->title. What about if we want to prevent writing to the property directly from outside, but keeping access it. This is where the Asymmetric visibility comes into place. 

The Asymmetric Visibility feature in PHP 8.4 allows us to define a different visibility modifier on read and write contexts for class properties.

Let’s redeclare property $title by allowing public read and preventing writing from outside:

class Post
{
    public private(set) string $title = "";

    public function __construct(string $title = "")
    {
        $this->title = "title";
    }
}

Now the property can be set only when initializing the class. With this code if you run the above script you will get an error like this:

Fatal error: Uncaught Error: Cannot modify private(set) property Post::$title from global scope

This is valid:

$post = new Post("post title");

echo $post->title;

From this code the Asymmetric visibility can be defined like so:

<read visibility> <set visibility>(set) <type> $property

 

Asymmetric visibility also works with Property Hooks to disallows setting property from outside:

class Post
{
    public private(set) string $title {
        set(string $value) {
            $this->title = $value;
        }
    }

    public function __construct(string $title)
    {
        $this->title = $title;
    }
}

This is valid:

$post = new Post("post title");

echo $post->title;

This is invalid:

$post = new Post("post title");

$post->title = "updated title";    // invalid

echo $post->title;

 

  • JIT Changes

Just-in-Time Compilation (JIT) comes with PHP 8.0 which is disabled by default. To enable it set the INI variable opcache.jit_buffer_size.

< PHP 8.4 the configuration:

opcache.jit=tracing
opcache.jit_buffer_size=0

Now with PHP 8.4 the configuration becomes:

opcache.jit=disable
opcache.jit_buffer_size=64M

 

  • New HTML5 Support

A new class added in PHP 8.4 in related to DOM manipulation which is the HTMLDocument available in the \Dom namespace:

$doc = \Dom\HTMLDocument::createFromString($contents);
$doc = HTMLDocument::createEmpty();
$doc = HTMLDocument::createFromFile($path);

 

  • New request_parse_body() Function

In PHP apps typically we manipulate post data using $_POST and $_FILES superglobals. However there are a limitation for other HTTP methods like PUT and PATCH especially for REST Webservices which depends on other HTTP methods like PUT and PATCH or DELETE. In PHP 8.4 new function added for this purpose request_parse_body():

[$_POST, $_FILES] = request_parse_body();

The function return an array of two items, where the first item contains the $_POST data and the second item contains the $_FILES data.

 

  • Dealing with exit() and die() as Functions

In PHP exit() and die() are language constructs not functions for example it doesn’t support named arguments and couldn’t be passed as callable and it can be written as exit; or exit(0). With PHP 8.4 this behavior change and exit() and die() will be treated as functions.

 

Deprecations

  • Implicit Nullable Types not allowed

In PHP 8.4 you have to explicitly declare a value that have a null value using the nullable type like so:

function getItems(string $a, ?string $b = null) {}

 

  • Deprecation of GET/POST sessions

Sessions used to track user state. In PHP we can also use GET/POST to store user state via disabling the setting session.use_only_cookies and session.use_trans_sid INI variables. By default, “session.use_only_cookies” is enabled, and “session.use_trans_sid” is disabled. Starting in PHP 8.4, if either value is toggled differently, PHP will raise a deprecation warning

 

Additional New PHP 8.4 Features

 

0 0 votes
Article Rating

What's your reaction?

Excited
0
Happy
0
Not Sure
0
Confused
0

You may also like

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments