What is New in PHP 8.3
PHP 8.3 introduces a range of helpful improvements and new capabilities to the language. This release focuses on better type safety, cleaner syntax, enhanced security, and more efficient operations. Key additions include support for typed constants in classes, a new attribute for method overriding checks, and useful new functions like JSON validation.
Key New Features
Typed Class Constants
Class, interface, trait, and enum constants can now declare explicit types. This ensures type consistency when constants are overridden or implemented, preventing subtle bugs.
In previous versions, type mismatches were silently allowed:
interface Example {
const DATA = 'string value';
}
class Test implements Example {
const DATA = []; // No error before PHP 8.3
}
PHP 8.3 enforces the declared type and throws an error on mismatch:
interface Example {
const string DATA = 'PHP 8.3';
}
class Test implements Example {
const string DATA = []; // Fatal error: Type mismatch
}
Dynamic Class Constant and Property Access
Accessing class constants dynamically is now simpler and more readable using a new syntax.
Old approach required string concatenation:
class Sample {
const VERSION = '8.3';
}
$constName = 'VERSION';
var_dump(constant('Sample::' . $constName));
New cleaner syntax:
class Sample {
const VERSION = '8.3';
}
$constName = 'VERSION';
var_dump(Sample::{$constName});
The same syntax also works for dynamic property access on objects.
The #[\Override] Attribute
This built-in attribute verifies that a method actually overrides a parent method or implements an interface method. It catches common typos at runtime.
Without the attribute, misspelled methods silently fail to override:
class Child extends Parent {
public function saveData() { ... } // Typo: meant to be saveDate()
}
With the attribute, PHP throws an error if no matching parent method exists:
class Child extends Parent {
#[\Override]
public function saveData() { ... } // Error if no parent method matches
}
Deep Cloning of Readonly Objects
Readonly properties can now be reassigned inside the __clone() method, enabling proper deep cloning of objects with readonly data.
readonly class Config {
public function __construct(public Database $db) {}
public function __clone(): void {
$this->db = clone $this->db; // Allowed in PHP 8.3
}
}
New json_validate() Function
A lightweight function to check if a string is valid JSON without decoding it fully. It is faster and uses less memory than json_decode() when only validation is needed.
json_validate('{"name": "PHP", "version": 8.3}'); // true
json_validate('invalid json'); // false
Random Extension Improvements
The Random extension gains new methods for more flexible and unbiased random value generation:
Random\Randomizer::getBytesFromString()- Generate random bytes using only characters from a provided string.Random\Randomizer::getFloat(),pickArrayValue(), and others for unbiased floating-point and array selection.
Command Line Linter Supports Multiple Files
The built-in linter can now check syntax for multiple files in one command:
php -l file1.php file2.php file3.php
New Functions and Methods
Several new functions and class methods have been added across core and extensions.
| Extension | New Functions/Methods |
|---|---|
| Core | json_validate(), str_increment(), str_decrement() |
| Date/Time | Improved exception handling in many operations |
| DOM | DOMElement::getAttributeNames(), DOMElement::insertAdjacentElement(), DOMElement::insertAdjacentText(), DOMElement::toggleAttribute(), DOMNode::contains(), DOMNode::getRootNode(), and more |
| Multibyte String | mb_str_pad() |
| LDAP | ldap_connect_wallet(), ldap_exop_sync() |
| POSIX | posix_sysconf(), posix_pathconf(), posix_fpathconf(), posix_eaccess() |
| Reflection | ReflectionMethod::createFromMethodName() |
| Socket | socket_atmark() |
| Zip | ZipArchive::getArchiveFlag() |
Additional changes include support for readonly anonymous classes and improved php.ini directive handling with default value syntax.
Backward Incompatible Changes
PHP 8.3 includes several behavior changes that may affect existing code:
- Date and time functions now throw specific exceptions instead of warnings on errors.
- Negative string offsets on empty strings and array access behavior changes in certain edge cases.
- Stricter handling of static properties in traits.
- Some INI directives and constants renamed or removed.
- SQLite3 uses exceptions by default for error reporting.
- Calling
get_class()orget_parent_class()without parameters is deprecated.
Review the migration guide when upgrading to ensure compatibility.
Performance and Other Improvements
This release delivers general performance optimizations, numerous bug fixes, and internal code cleanups. The Random extension continues to mature with more secure and flexible random generation tools.