Explore PHP 8.3: Typed Class Constants, Readonly Clone, and New Randomizer APIs

PHP 8.3 introduces a range of backend enhancements—including explicit typed class constants, dynamic constant access, the #[\Override] attribute, deep‑clone support for readonly properties, a new json_validate() function, and expanded Randomizer methods—plus numerous new DOM, Intl, LDAP, and POSIX functions, while deprecating several legacy features.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Explore PHP 8.3: Typed Class Constants, Readonly Clone, and New Randomizer APIs

Introduction

PHP 8.3 is a major release of the PHP language that adds many new features, performance improvements, bug fixes, and general clean‑ups.

Typed Class Constants

interface I {
    const string PHP = 'PHP 8.3';
}

class Foo implements I {
    const string PHP = [];
}
// Fatal error: Cannot use array as value for class constant
// Foo::PHP of type string

Class constants can now be declared with explicit types, and assigning a value of a mismatched type triggers a fatal error.

Dynamic Access to Class Constants

class Foo {
    const PHP = 'PHP 8.3';
}

$searchableConstant = 'PHP';
var_dump(Foo::{$searchableConstant});

Constants can be accessed dynamically using a variable that holds the constant name.

New #[\Override] Attribute

use PHPUnit\Framework\TestCase;

final class MyTest extends TestCase {
    protected $logFile;

    protected function setUp(): void {
        $this->logFile = fopen('/tmp/logfile', 'w');
    }

    #[\Override]
    protected function taerDown(): void {
        fclose($this->logFile);
        unlink('/tmp/logfile');
    }
}
// Fatal error: MyTest::taerDown() has #[\Override] attribute, but no matching parent method exists
Adding the #[\Override] attribute tells PHP to ensure a method with the same name exists in a parent class or interface, helping catch accidental mismatches during refactoring.

Readonly Property Deep Clone

class PHP {
    public string $version = '8.2';
}

readonly class Foo {
    public function __construct(public PHP $php) {}

    public function __clone(): void {
        $this->php = clone $this->php;
    }
}

$instance = new Foo(new PHP());
$cloned = clone $instance;
$cloned->php->version = '8.3';
The readonly attribute now permits a single modification inside __clone , enabling deep cloning of readonly properties.

New json_validate() Function

var_dump(json_validate('{ "test": { "foo": "bar" } }')); // true
json_validate() checks whether a string is syntactically valid JSON, offering a more efficient alternative to json_decode() when only validation is needed.

Randomizer Enhancements

Randomizer::getBytesFromString()

// A \Random\Engine may be passed for seeding,
// the default is the secure engine.
$randomizer = new \Random\Randomizer();

$randomDomain = sprintf(
    "%s.example.com",
    $randomizer->getBytesFromString('abcdefghijklmnopqrstuvwxyz0123456789', 16),
);

echo $randomDomain;
This new method generates a random string composed of a specific number of bytes, useful for creating identifiers such as domain names.

Randomizer::getFloat() and Randomizer::nextFloat()

$randomizer = new \Random\Randomizer();

$temperature = $randomizer->getFloat(
    -89.2,
    56.7,
    \Random\IntervalBoundary::ClosedClosed,
);

$chanceForTrue = 0.1;
// Randomizer::nextFloat() is equivalent to
// Randomizer::getFloat(0, 1, \Random\IntervalBoundary::ClosedOpen).
// The upper bound, i.e. 1, will not be returned.
$myBoolean = $randomizer->nextFloat() < $chanceForTrue;
Generating unbiased floating‑point numbers within a specific interval is non‑trivial; these methods provide reliable, boundary‑aware random floats.

New Classes, Interfaces, and Functions

DOMElement::getAttributeNames(), ::insertAdjacentElement(), ::insertAdjacentText(), ::toggleAttribute()

DOMNode::contains(), ::getRootNode(), ::isEqualNode()

DOMNameSpaceNode::contains()

DOMParentNode::replaceChildren()

IntlCalendar::setDate(), ::setDateTime()

IntlGregorianCalendar::createFromDate(), ::createFromDateTime()

ldap_connect_wallet() and ldap_exop_sync()

mb_str_pad()

posix_sysconf(), posix_pathconf(), posix_fpathconf(), posix_eaccess()

ReflectionMethod::createFromMethodName()

socket_atmark()

str_increment(), str_decrement(), stream_context_set_options()

ZipArchive::getArchiveFlag()

Support for custom EC parameters in OpenSSL extension

INI setting zend.max_allowed_stack_size to control maximum stack size

Deprecations and Backward‑Incompatible Changes

More appropriate Date/Time exceptions

Negative index handling in empty arrays now yields n + 1 instead of 0 Changes to range() behavior

Changes to redeclaring static properties in traits

Constant U_MULTIPLE_DECIMAL_SEPERATORS renamed to U_MULTIPLE_DECIMAL_SEPARATORS Mt19937 variant MT_RAND_PHP deprecated ReflectionClass::getStaticProperties() no longer returns empty

INI directives assert.active, assert.bail, assert.callback, assert.exception, assert.warning deprecated

Calling get_class() or get_parent_class() without arguments deprecated

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendPHPreadonlyNew Featuresrandomizertyped constants8.3
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.