What's New in PHP 8.3?
PHP 8.3 continues the language's strong momentum, delivering refinements that make everyday PHP development cleaner, safer, and more expressive. Whether you're upgrading an existing application or starting fresh, this guide walks you through the most important changes you should know.
Table of Contents
- Typed Class Constants
- json_validate() Function
- Readonly Property Amendments
- Dynamic Class Constant Fetch
- Notable Deprecations
Typed Class Constants
One of the most-requested features finally lands in PHP 8.3: you can now declare types on class, interface, and enum constants.
interface HasVersion {
const string VERSION = '1.0.0';
}
class Config implements HasVersion {
const string VERSION = '2.5.1'; // Must be a string
const int MAX_RETRIES = 3;
}
This enforces correctness at the class level and makes APIs more predictable. Before this, constants could silently hold the wrong type, causing subtle runtime bugs. Now, PHP throws a TypeError if a child class overrides a constant with an incompatible type.
The json_validate() Function
Developers have long relied on json_decode() followed by a json_last_error() check to validate JSON strings — a wasteful approach that parses the entire structure just to discard it. PHP 8.3 introduces a dedicated function:
$json = '{"name": "PHP Weekly", "version": 8}';
if (json_validate($json)) {
echo "Valid JSON!";
} else {
echo "Invalid JSON.";
}
This is significantly faster when you only need to verify validity without decoding, particularly useful in input validation pipelines and middleware layers.
Readonly Property Amendments
PHP 8.3 clarifies and expands the behavior of readonly properties. Notably, you can now reinitialize readonly properties during cloning by using clone with property overrides — a pattern that was previously impossible without reflection hacks.
class User {
public function __construct(
public readonly int $id,
public readonly string $name,
) {}
}
$original = new User(1, 'Alice');
$clone = clone $original; // id and name carry over cleanly
Dynamic Class Constant Fetch
PHP 8.3 allows you to fetch class constants and enum members dynamically using a variable:
class Status {
const ACTIVE = 'active';
const INACTIVE = 'inactive';
}
$key = 'ACTIVE';
echo Status::{$key}; // Outputs: active
This mirrors the existing support for dynamic property and method access, making it easier to build configuration-driven or metadata-heavy systems.
Notable Deprecations to Watch
- Passing negative
$widthstomb_strimwidth()is now deprecated. - The
uflag inrange()with non-integer steps raises a deprecation warning. - Calling
get_class()without arguments inside a static context is deprecated — usestatic::classinstead.
Should You Upgrade?
PHP 8.3 is a stable, production-ready release. For most applications, upgrading from 8.2 is straightforward. Run your test suite with --deprecations warnings enabled, address any flagged calls, and you're likely good to go. The performance and safety gains make the upgrade well worth the effort.