Articles

Introducing PHP 8.2 Features

Introducing PHP 8.2 Features

PHP 8.2 version released and contains many language updates such as readonly classes, false true and null types, dynamic property deprecations and many more, see them in this article.

 

 

 

Readonly Classes 

PHP 8.2 includes the readonly classes feature and this is an update to the readonly properties feature in PHP 8.1. If you remember in PHP 8.1 the readonly properties which allow to set a property as readonly using the “readonly” keyword. 

The same concept applies on classes, when a class is marked as readonly then all properties of this class will be readonly as well.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
readonly class Post
{
public int $id;
public string $title;
public function __construct(int $id, string $title)
{
$this->id = $id;
$this->title = $title;
}
}
readonly class Post { public int $id; public string $title; public function __construct(int $id, string $title) { $this->id = $id; $this->title = $title; } }
readonly class Post
{
    public int $id;

    public string $title;

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

Here we mark the class as readonly by preceding the class name with the “readonly” keyword.

Create an instance of the class:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$post = new Post(20, "New Post");
echo $post->title;
$post = new Post(20, "New Post"); echo $post->title;
$post = new Post(20, "New Post");
echo $post->title;

By creating an instance we initialized the readonly properties as well. Now if we tried to set any property in this class like the title:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$post->title = "Updated Post";
$post->title = "Updated Post";
$post->title = "Updated Post";

It will show an error like so:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Fatal error: Uncaught Error: Cannot modify readonly property Post::$title in ...
Fatal error: Uncaught Error: Cannot modify readonly property Post::$title in ...
Fatal error: Uncaught Error: Cannot modify readonly property Post::$title in ...

Because by logic readonly properties should be initialized once and any attempt to initialize it again it will trigger error.

 

Readonly class limitations

  • To apply the readonly keyword to a class, all properties of this class must have an explicit type. In the previous example if we omit the type from the $title property:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public $title;
public $title;
public $title;

This error will be triggered:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Fatal error: Readonly property Post::$title must have type in ...
Fatal error: Readonly property Post::$title must have type in ...
Fatal error: Readonly property Post::$title must have type in ...
  • Another limitation for static properties, static properties cannot be used in readonly classes:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
readonly class Post
{
....
....
public static int $userid;
....
....
}
readonly class Post { .... .... public static int $userid; .... .... }
readonly class Post
{
    ....
    ....

    public static int $userid;

    ....
    ....
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Fatal error: Static property Post::$userid cannot be readonly in ...
Fatal error: Static property Post::$userid cannot be readonly in ...
Fatal error: Static property Post::$userid cannot be readonly in ...

Learn more about readonly propery here>>>

 

true, false, null as standalone types

Another feature in PHP 8.2 is allowing true, false and null as standalone types. In versions prior to PHP 8.2 there is a bool type used for (true, false) and the string|null for nullable type.

< PHP 8.2

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function isNegative(): bool
{
return false;
}
function isPositive(): bool
{
return true;
}
function maybeNull(): string|null
{
return null;
}
function isNegative(): bool { return false; } function isPositive(): bool { return true; } function maybeNull(): string|null { return null; }
function isNegative(): bool
{
    return false;
}

function isPositive(): bool
{
    return true;
}

function maybeNull(): string|null
{
    return null;
} 

 PHP 8.2

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function isNegative(): false
{
return false;
}
function isPositive(): true
{
return true;
}
function maybeNull(): null
{
return null;
}
function isNegative(): false { return false; } function isPositive(): true { return true; } function maybeNull(): null { return null; }
function isNegative(): false
{
    return false;
}

function isPositive(): true
{
    return true;
}

function maybeNull(): null
{
    return null;
} 

However the bool type is a generic type and can be true or false. So to use the new true/false types you have to be sure that the return type is what you expect, for example in the above function if we modify the function to return true it will trigger an error:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function isNegative(): false
{
return true; // invalid as the return type is false
}
function isNegative(): false { return true; // invalid as the return type is false }
function isNegative(): false
{
    return true;       // invalid as the return type is false
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Fatal error: Uncaught TypeError: isNegative(): Return value must be of type false, bool returned in ...
Fatal error: Uncaught TypeError: isNegative(): Return value must be of type false, bool returned in ...
Fatal error: Uncaught TypeError: isNegative(): Return value must be of type false, bool returned in ...

 

Constants in traits

Now in PHP 8.2 it’s possible to use a constant in trait and reference that constant in the class that uses the trait

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
trait WithError
{
public const SUCCESS = 200;
public const NOTFOUND = 404;
}
trait WithError { public const SUCCESS = 200; public const NOTFOUND = 404; }
trait WithError
{
    public const SUCCESS = 200;
    public const NOTFOUND = 404;
}

You can’t use the const directly from the trait eg:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var_dump(WithError::NOTFOUND); // Invalid
var_dump(WithError::NOTFOUND); // Invalid
var_dump(WithError::NOTFOUND);   // Invalid

Instead use it through a class:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class Post
{
use WithError;
public function save()
{
// hide class specific code
return self::SUCCESS;
}
}
var_dump(Post::NOTFOUND); // 404
$post = new Post();
var_dump($post->save()); // 200
class Post { use WithError; public function save() { // hide class specific code return self::SUCCESS; } } var_dump(Post::NOTFOUND); // 404 $post = new Post(); var_dump($post->save()); // 200
class Post
{
    use WithError;

    public function save()
    {
        // hide class specific code

        return self::SUCCESS;
    }
}

var_dump(Post::NOTFOUND);         // 404

$post = new Post();
var_dump($post->save());          // 200

 

New random extension

As of PHP 8.2 most of the random generation functions will be moved to the new random extension in PHP 8.2. The “random” extension provides a new object-oriented API to random number generation. In addition to this a new class added \Random\Randomizer

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$r = new Random\Randomizer();
// return random integer between two integers
echo $r->getInt(1, 200);
$r = new Random\Randomizer(); // return random integer between two integers echo $r->getInt(1, 200);
$r = new Random\Randomizer();

// return random integer between two integers
echo $r->getInt(1, 200);
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
echo bin2hex($r->getBytes(8)), "\n";
echo bin2hex($r->getBytes(8)), "\n";
echo bin2hex($r->getBytes(8)), "\n";
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$countries = ['usa' => 'united states', 'uk' => 'england', 'fr' => 'france'];
var_dump($r->shuffleArray($countries));
$countries = ['usa' => 'united states', 'uk' => 'england', 'fr' => 'france']; var_dump($r->shuffleArray($countries));
$countries = ['usa' => 'united states', 'uk' => 'england', 'fr' => 'france'];

var_dump($r->shuffleArray($countries));
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
echo $r->shuffleBytes("Hello World!");
echo $r->shuffleBytes("Hello World!");
echo $r->shuffleBytes("Hello World!");

Checkout my article here about the random extension.

 

Dynamic Properties Deprecations

The creation of dynamic properties is deprecated to help avoid mistakes and typos. Consider this class:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class User
{
public string $firstname;
}
$user = new User();
$user->firstname = "John";
$user->lastname = "Doe"; // dynamic property
class User { public string $firstname; } $user = new User(); $user->firstname = "John"; $user->lastname = "Doe"; // dynamic property
class User
{
    public string $firstname;
}

$user = new User();
$user->firstname = "John";
$user->lastname = "Doe";        // dynamic property

See here the $lastname property, this is a dynamic property which is not explicitly declared inside the class. Before PHP 8.2 this code is working fine. However in PHP 8.2 it will show a deprecation notice similar to this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Deprecated: Creation of dynamic property User::$lastname is deprecated in ...
Deprecated: Creation of dynamic property User::$lastname is deprecated in ...
Deprecated: Creation of dynamic property User::$lastname is deprecated in ...

To get this to work in PHP 8.2, you have many options: the first is to declare the property (preferred):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class User
{
public string $firstname;
public string $lastname;
}
class User { public string $firstname; public string $lastname; }
class User
{
    public string $firstname;
    public string $lastname;
}

The other option is by adding #[\AllowDynamicProperties] attribute to the class:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#[\AllowDynamicProperties]
class User
{
public string $firstname;
}
#[\AllowDynamicProperties] class User { public string $firstname; }
#[\AllowDynamicProperties]
class User
{
    public string $firstname;
}

The magic methods __set()/__get() is not affected by this change.

stdClass still allow dynamic properties

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$user = new \stdClass();
$user->name = "John Doe";
$user = new \stdClass(); $user->name = "John Doe";
$user = new \stdClass();
$user->name = "John Doe";

 

New classes and functions

 

0 0 votes
Article Rating

What's your reaction?

Excited
48
Happy
1
Not Sure
1
Confused
1

You may also like

Subscribe
Notify of
guest


0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments