Home » Releases » PHP 8.2 »

PHP 8.2 Code Comparisons

Explore PHP 8.2

Readonly Classes

PHP 8.2 introduces readonly classes. Declaring a class as readonly makes all its properties implicitly readonly, preventing dynamic property creation and ensuring immutable state without needing to mark every individual property.
Before PHP 8.2
class BlogData
{
    public readonly string $title;

    public readonly Status $status;

    public function __construct(string $title, Status $status)
    {
        $this->title = $title;
        $this->status = $status;
    }
}
PHP 8.2 or Later
readonly class BlogData
{
    public string $title;

    public Status $status;

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

Disjunctive Normal Form (DNF) Types

DNF types allow us to combine union and intersection types, following a strict rule: when combining union and intersection types, intersection types must be grouped with brackets.
Before PHP 8.2
class Foo {
    public function bar(mixed $entity) {
        if ((($entity instanceof A) && ($entity instanceof B)) || ($entity === null)) {
            return $entity;
        }

        throw new Exception('Invalid entity');
    }
}
PHP 8.2 or Later
class Foo {
    public function bar((A&B)|null $entity) {
        return $entity;
    }
}

Allow null, false, and true as stand-alone types

PHP 8.2 permits null, false, and true to be used as standalone types in type declarations, enabling more precise typing for methods that return or accept specific literal values.
Before PHP 8.2
class Falsy
{
    public function almostFalse(): bool { /* ... */ *}

    public function almostTrue(): bool { /* ... */ *}

    public function almostNull(): string|null { /* ... */ *}
}
PHP 8.2 or Later
class Falsy
{
    public function alwaysFalse(): false { /* ... */ *}

    public function alwaysTrue(): true { /* ... */ *}

    public function alwaysNull(): null { /* ... */ *}
}

New "Random" extension

The "random" extension provides a new object-oriented API to random number generation. Instead of relying on a globally seeded random number generator (RNG) using the Mersenne Twister algorithm the object-oriented API provides several classes ("Engine"s) providing access to modern algorithms that store their state within objects to allow for multiple independent seedable sequences. The \Random\Randomizer class provides a high-level interface to use the engine's randomness to generate a random integer, to shuffle an array or string, to select random array keys and more.
PHP 8.2 or Later
use Random\Engine\Xoshiro256StarStar;
use Random\Randomizer;

$blueprintRng = new Xoshiro256StarStar(
    hash('sha256', "Example seed that is converted to a 256 Bit string via SHA-256", true)
);

$fibers = [];
for ($i = 0; $i < 8; $i++) {
    $fiberRng = clone $blueprintRng;
    // Xoshiro256**'s 'jump()' method moves the blueprint ahead 2**128 steps, as if calling
    // 'generate()' 2**128 times, giving the Fiber 2**128 unique values without needing to reseed.
    $blueprintRng->jump();

    $fibers[] = new Fiber(function () use ($fiberRng, $i): void {
        $randomizer = new Randomizer($fiberRng);

        echo "{$i}: " . $randomizer->getInt(0, 100), PHP_EOL;
    });
}

// The randomizer will use a CSPRNG by default.
$randomizer = new Randomizer();

// Even though the fibers execute in a random order, they will print the same value
// each time, because each has its own unique instance of the RNG.
$fibers = $randomizer->shuffleArray($fibers);
foreach ($fibers as $fiber) {
    $fiber->start();
}

Constants in traits

You cannot access the constant through the name of the trait, but, you can access the constant through the class that uses the trait.
PHP 8.2 or Later
trait Foo
{
    public const CONSTANT = 1;
}

class Bar
{
    use Foo;
}

var_dump(Bar::CONSTANT); // 1
var_dump(Foo::CONSTANT); // Error

Deprecate dynamic properties RFC Doc

The creation of dynamic properties is deprecated to help avoid mistakes and typos, unless the class opts in by using the #[\AllowDynamicProperties] attribute. stdClass allows dynamic properties. Usage of the __get/__set magic methods is not affected by this change.
PHP 8.2 or Later
class User
{
    public $name;
}

$user = new User();
$user->last_name = 'Doe';

$user = new stdClass();
$user->last_name = 'Doe';
8.2 or Later
class User
{
    public $name;
}

$user = new User();
$user->last_name = 'Doe'; // Deprecated notice

$user = new stdClass();
$user->last_name = 'Doe'; // Still allowed