Neue Funktionen und Verbesserungen in PHP 8.3: Eine vollständige technische Referenz
PHP 8.3 ist eine bedeutende Minor-Version der PHP-Sprache, die wesentliche Verbesserungen am JIT-Compiler, dem Typsystem, Readonly-Properties und den Kern-Array-/String-Funktionen liefert. Veröffentlicht am 23. November 2023, führt sie typisierte Klassenkonstanten, json_validate(), array_is_list()-Verfeinerungen, Randomizer-Ergänzungen und Deep-Cloning von Readonly-Properties ein — Änderungen, die sich direkt auf die Anwendungsleistung, Korrektheit des Codes und Wartbarkeit auf Produktionsservern auswirken.
Wenn Sie PHP-basierte Workloads in einer VPS Hosting-Umgebung oder auf einem Dedicated Server betreiben, ist das Verständnis jeder PHP 8.3-Änderung keine Option — es ist eine Voraussetzung für fundierte Upgrade-Entscheidungen, die Vermeidung stiller Regressionen und die Erzielung messbarer Leistungsgewinne.
Was sich zwischen PHP 8.2 und PHP 8.3 geändert hat
Bevor wir auf einzelne Features eingehen, lohnt es sich, den Umfang dieses Releases zu klären. PHP 8.3 ist kein grundlegender Neuschrieb. Es ist ein präzises Upgrade, das langjährige Lücken im Typsystem schließt, die JIT-Pipeline stärkt und Hilfsfunktionen hinzufügt, die zuvor Userland-Workarounds erforderten. Die folgende Tabelle ordnet die wirkungsvollsten Änderungen ihren PHP 8.2-Entsprechungen zu.
| Feature / Verhalten | PHP 8.2 | PHP 8.3 |
|---|---|---|
| Typisierte Klassenkonstanten | Nicht unterstützt | Vollständig unterstützt |
json_validate() | Nicht verfügbar | Nativ verfügbar |
| Readonly-Property-Cloning | Nicht möglich | Unterstützt via clone |
array_is_list() | Verfügbar | Verhalten unverändert, aber breitere Adoptionsmuster |
| Dynamischer Klassenkonstanten-Abruf | Syntaxfehler | Unterstützt via ClassName::{$const} |
Randomizer::getBytesFromString() | Nicht verfügbar | Verfügbar |
Randomizer::getFloat() / nextFloat() | Nicht verfügbar | Verfügbar |
#[Override]-Attribut | Nicht verfügbar | Verfügbar |
Deprecation: mt_rand implizites Seeding | Nicht veraltet | Veraltet |
| Fiber-Stack-Größe ini-Direktive | Nicht konfigurierbar | fiber.stack_size hinzugefügt |
| JIT-Tracing-Verbesserungen | Basis-Tracing | Verbessertes IR und Loop-Handling |
str_contains mit Arrays | Nicht unterstützt | Weiterhin nicht unterstützt (Fehler im Quellartikel — siehe unten) |
> Kritische Korrektur: Der Quellartikel behauptet fälschlicherweise, dass str_contains() in PHP 8.3 ein Array von Strings akzeptiert. Dies ist sachlich falsch. str_contains() akzeptiert nur zwei String-Argumente. Das Übergeben eines Arrays löst einen TypeError aus. Der korrekte Ansatz zur Suche eines Teilstrings über mehrere Strings hinweg ist array_filter() kombiniert mit str_contains(), oder in_array() für exakte Übereinstimmungen.
JIT-Kompilierung in PHP 8.3: Was sich tatsächlich geändert hat
Hintergrund: Wie PHP JIT funktioniert
PHPs JIT-Compiler, experimentell in PHP 8.0 eingeführt, arbeitet als Erweiterung des OPcache-Subsystems. Er kompiliert häufig ausgeführte Bytecode-Pfade zur Laufzeit in nativen Maschinencode und umgeht dabei den Zend-VM-Interpreter für diese Pfade. PHP 8.3 wird mit einem wesentlich überarbeiteten JIT-Backend ausgeliefert, das die bei der Kompilierung verwendete Zwischendarstellung (IR) verbessert.
Das neue IR-basierte JIT in PHP 8.3 (entwickelt von Dmitry Stogov) ersetzt die Code-Generierungsschicht des älteren Tracing-JIT durch eine ordentliche SSA-Form-Zwischendarstellung. Dies ermöglicht bessere Registerzuweisung, Eliminierung toten Codes und Loop-Invariant-Hoisting — Optimierungen, die in der vorherigen Architektur strukturell unmöglich waren.
JIT korrekt aktivieren
Der Originalartikel zeigt php -d jit=on script.php, was unvollständig ist. JIT erfordert, dass OPcache aktiv ist. Die korrekte minimale Konfiguration für einen CLI-Benchmark oder eine Produktions-php.ini lautet:
; php.ini
opcache.enable=1
opcache.enable_cli=1
opcache.jit_buffer_size=128M
opcache.jit=tracingIn einem Webserver-Kontext (FPM oder Apache mod_php) ist opcache.enable_cli irrelevant, aber opcache.jit_buffer_size muss ungleich null sein, sonst deaktiviert sich JIT stillschweigend. Eine häufige Produktionsfalle ist das Setzen von jit_buffer_size=0 in einer gemeinsamen php.ini und das Wundern, warum JIT keine Wirkung zeigt.
Wann JIT messbare Gewinne liefert
JIT ist nicht universell vorteilhaft. Seine Gewinne konzentrieren sich auf CPU-gebundene Workloads:
- Hochwertige Ziele: Mathematische Berechnungen, Bildverarbeitung, Machine-Learning-Inferenz, Spiellogik, CSV-/Daten-Parsing-Schleifen, kryptografische Operationen im Userland.
- Geringwertige Ziele: Typische CRUD-Webanwendungen, bei denen der Engpass I/O ist (Datenbankabfragen, Dateisystem, Netzwerk). In diesen Fällen kann der JIT-Overhead durch die Kompilierung den Speicherverbrauch leicht erhöhen, mit vernachlässigbarer Durchsatzverbesserung.
- Negative Fälle: Anwendungen mit extrem vielfältigen Code-Pfaden (große Frameworks mit starker Reflection) können dazu führen, dass JIT den Buffer überlastet und Deoptimierungs-Overhead verursacht.
Eine praktische Regel: Benchmarken Sie zuerst mit opcache.jit=tracing. Wenn Sie bei Ihrer tatsächlichen Workload weniger als 3% Verbesserung sehen, deaktivieren Sie JIT, um den Buffer-Speicher für OPcaches Opcode-Cache zurückzugewinnen, der allen PHP-Anwendungen gleichmäßig zugute kommt.
Typisierte Klassenkonstanten
Dies ist wohl die wirkungsvollste Typsystem-Ergänzung in PHP 8.3 für große Codebasen.
Das Problem, das es löst
Vor PHP 8.3 hatten Klassenkonstanten keinen erzwungenen Typ. Eine Kindklasse konnte eine Konstante mit einem völlig inkompatiblen Typ neu definieren, und PHP würde keinen Fehler auslösen, bis zur Laufzeit — oder gar nicht, je nachdem, wie die Konstante verwendet wurde.
// PHP 8.2 — no type enforcement
interface StatusCode {
const SUCCESS = 200; // implicitly int
}
class BrokenStatus implements StatusCode {
const SUCCESS = "two hundred"; // silently accepted — a maintenance nightmare
}PHP 8.3-Lösung
// PHP 8.3 — type is enforced at definition and inheritance
interface StatusCode {
const int SUCCESS = 200;
}
class BrokenStatus implements StatusCode {
const int SUCCESS = "two hundred";
// Fatal error: Cannot use string as value for typed class constant
// BrokenStatus::SUCCESS of type int
}Alle skalaren Typen (int, float, string, bool), array, null, Union-Typen und Intersection-Typen sind für Konstantentypdeklarationen gültig. Die Typen never und void sind nicht erlaubt. Dieses Feature integriert sich sauber mit statischen Analysetools wie PHPStan und Psalm und ermöglicht strengere Interface-Verträge ohne Laufzeit-Overhead.
Dynamischer Klassenkonstanten- und Enum-Member-Abruf
PHP 8.3 erlaubt das Abrufen von Klassenkonstanten und Enum-Membern mithilfe eines Laufzeitausdrucks in der ::{}-Syntax.
class Direction {
const string NORTH = 'north';
const string SOUTH = 'south';
}
$direction = 'NORTH';
echo Direction::{$direction}; // outputs: northZuvor erforderte dies constant() oder einen match-Ausdruck, die beide ausführlich und fehleranfällig sind. Die neue Syntax funktioniert auch mit Enums:
enum Color {
case Red;
case Blue;
}
$name = 'Red';
$color = Color::{$name}; // Color::RedZu beachtender Grenzfall: Wenn die Variable einen Namen enthält, der keiner definierten Konstante oder keinem Enum-Case entspricht, wirft PHP eine Error-Exception — keine Warnung. Umschließen Sie dynamische Abrufe mit einem try/catch-Block oder validieren Sie mit defined() / enum_exists() vor der Verwendung.
Die json_validate()-Funktion
Warum dies in der Produktion wichtig ist
Vor PHP 8.3 war der idiomatische Weg zur Validierung eines JSON-Strings ohne Dekodierung:
json_decode($input);
$isValid = json_last_error() === JSON_ERROR_NONE;Dieser Ansatz dekodiert das JSON vollständig in eine PHP-Struktur und belegt dabei Speicher proportional zur Payload-Größe. Für reine Validierungs-Pipelines — API-Gateways, Message-Queue-Consumer, Webhook-Empfänger — ist dies verschwenderisch.
Native Validierung in PHP 8.3
$payload = '{"user": "alex", "role": "admin"}';
if (json_validate($payload)) {
// safe to decode
$data = json_decode($payload, true);
}
// Invalid JSON
var_dump(json_validate('{invalid}')); // bool(false)json_validate() parst die JSON-Struktur, ohne einen PHP-Wertbaum zu konstruieren. Der Speicherverbrauch ist O(Tiefe) statt O(Größe), was es für große Payloads deutlich effizienter macht. Es akzeptiert auch die Parameter $depth und $flags konsistent mit json_decode().
Praxisanwendungsfall: Ein Webhook-Empfänger, der 50.000 Anfragen pro Minute verarbeitet, kann json_validate() verwenden, um fehlerhafte Payloads am Rand abzulehnen, bevor eine Deserialisierung stattfindet, was CPU- und Speicherlast erheblich reduziert.
Readonly-Properties: Unterstützung für Deep Cloning
PHP 8.2 führte Readonly-Properties ein, machte es aber unmöglich, sie auch beim Klonen von Objekten zu ändern. Dies zwang Entwickler zu umständlichen Workarounds — Factory-Methoden, Serialisierungs-Hacks oder dem vollständigen Verzicht auf Readonly für Value-Objekte.
PHP 8.3 löst dies, indem die magische Methode __clone() nun die Neuzuweisung von Readonly-Properties im Klon-Kontext erlaubt.
class ImmutablePoint {
public function __construct(
public readonly float $x,
public readonly float $y,
) {}
public function withX(float $x): static {
$clone = clone $this;
$clone->x = $x; // Legal in PHP 8.3 within __clone context
return $clone;
}
}
$point = new ImmutablePoint(1.0, 2.0);
$moved = $point->withX(5.0);
echo $moved->x; // 5.0
echo $point->x; // 1.0 — original unchangedDieses Muster ist grundlegend für unveränderliche Value-Objekte im Domain-Driven Design. Ohne es war Readonly für komplexe Domänenmodelle weitgehend dekorativ.
Das #[Override]-Attribut
Das #[Override]-Attribut signalisiert PHP (und statischen Analysetools), dass eine Methode beabsichtigt, eine Methode einer Elternklasse oder eines Interfaces zu überschreiben. Wenn die Elternmethode nicht existiert, wirft PHP einen Kompilierzeitfehler.
class Base {
public function process(): void {}
}
class Child extends Base {
#[Override]
public function process(): void {
// If Base::process() is renamed or removed, this becomes a fatal error
}
}Dies ist besonders wertvoll in großen Teams, wo das Refactoring einer Basisklasse Überschreibungen in Kindklassen stillschweigend brechen kann. Das Attribut fungiert als Kompilierzeitvertrag und fängt eine Kategorie von Fehlern ab, die zuvor nur zur Laufzeit oder durch statische Analyse auftraten.
array_is_list() und korrekte Array-Klassifizierung
array_is_list() wurde in PHP 8.1 eingeführt, nicht in 8.3. Jedoch verdienen seine korrekten Verwendungsmuster eine präzise Dokumentation, da die Funktion häufig missverstanden wird.
Ein PHP-Array ist eine Liste genau dann, wenn:
- Es leer ist, oder
- Seine Schlüssel aufeinanderfolgende Ganzzahlen sind, die bei
0beginnen, ohne Lücken.
var_dump(array_is_list([])); // bool(true)
var_dump(array_is_list([0 => 'a', 1 => 'b'])); // bool(true)
var_dump(array_is_list(['a', 'b', 'c'])); // bool(true)
var_dump(array_is_list([1 => 'a', 0 => 'b'])); // bool(false) — wrong order
var_dump(array_is_list([0 => 'a', 2 => 'b'])); // bool(false) — gap at index 1
var_dump(array_is_list(['key' => 'value'])); // bool(false) — string keyPraktische Anwendung: Beim Serialisieren von Daten nach JSON bestimmt array_is_list(), ob die Ausgabe ein JSON-Array ([]) oder ein JSON-Objekt ({}) sein soll. Die Verwendung vor json_encode() verhindert die versehentliche Objekt-Serialisierung von numerisch indizierten Arrays, aus denen Elemente entfernt wurden.
Neue Randomizer-Methoden in PHP 8.3
Die in PHP 8.2 eingeführte RandomRandomizer-Klasse erhält drei wichtige Ergänzungen:
getBytesFromString()
$randomizer = new RandomRandomizer();
$token = $randomizer->getBytesFromString('abcdefghijklmnopqrstuvwxyz0123456789', 16);
echo $token; // e.g., "k3mz9xqp1wvn7yt2"Dies generiert einen kryptografisch sicheren zufälligen String aus einem angegebenen Alphabet — ein Muster, das für Token-Generierung, OTP-Codes und Slug-Erstellung benötigt wird. Zuvor erforderte dies eine manuelle Schleife mit random_int().
getFloat() und nextFloat()
$randomizer = new RandomRandomizer();
// Returns a float in [0.0, 1.0)
$value = $randomizer->nextFloat();
// Returns a float in a specified closed or half-open interval
$scaled = $randomizer->getFloat(1.5, 9.5, RandomIntervalBoundary::ClosedOpen);getFloat() verwendet den γ-Abschnitt-Algorithmus, um gleichmäßig verteilte Floats ohne den Modulo-Bias zu erzeugen, der naive Implementierungen betrifft. Dies ist entscheidend für Simulationen, probabilistische Algorithmen und A/B-Test-Frameworks, bei denen die Gleichmäßigkeit der Verteilung wichtig ist.
Deprecations und Entfernungen in PHP 8.3
Zu verstehen, was schrittweise abgeschafft wird, ist genauso wichtig wie zu wissen, was hinzugefügt wird. Das Ignorieren von Deprecations jetzt bedeutet fatale Fehler in PHP 9.0.
| Veraltetes Feature | Grund | Migrationspfad |
|---|---|---|
Aufruf von mt_rand() ohne expliziten Seed in einigen Kontexten | Inkonsistenz beim impliziten Seeding-Verhalten | Verwenden Sie RandomRandomizer |
ReflectionProperty::setValue() ohne Objekt bei nicht-statischen Methoden | Mehrdeutiges Verhalten | Übergeben Sie das Zielobjekt explizit |
Übergabe negativer $widths an mb_strimwidth() | Undefiniertes Verhalten | Eingabe vor dem Aufruf validieren |
ldap_connect() mit separaten Host/Port-Argumenten | Zugunsten der URI-Form veraltet | URI-String ldap://host:port verwenden |
range() mit nicht-ganzzahligem Schritt, der Floats erzeugt | Überraschende implizite Typumwandlung | Schritt explizit zu float casten |
Leistungs-Benchmarks: PHP 8.3 vs. frühere Versionen
Basierend auf veröffentlichten Benchmarks von Kinsta, Phoronix und dem PHP-Internals-Team mit Symfony Demo, WordPress und reinen Fibonacci-/Sortier-Workloads:
| Benchmark | PHP 8.1 | PHP 8.2 | PHP 8.3 |
|---|---|---|---|
| Symfony Demo (Req/Sek) | ~1.450 | ~1.520 | ~1.610 |
| WordPress (Req/Sek) | ~1.180 | ~1.240 | ~1.290 |
| Fibonacci (JIT, ms) | ~48 | ~44 | ~38 |
| Mandelbrot (JIT, ms) | ~210 | ~195 | ~170 |
| Nur OPcache (kein JIT) | Basis | +5% | +8% |
Die Gewinne sind konsistent, aber für I/O-gebundene Anwendungen nicht dramatisch. Die JIT-Verbesserungen in PHP 8.3 zeigen das signifikanteste Delta bei reinen Berechnungs-Workloads — bis zu 18% schneller als PHP 8.2 beim Mandelbrot-Benchmark.
Upgrade auf PHP 8.3: Praktische Server-seitige Checkliste
Wenn Sie Ihre eigene Server-Infrastruktur verwalten — ob auf einem VPS mit cPanel oder einem Bare-Metal-Dedicated Server — folgen Sie dieser Reihenfolge, bevor Sie Produktionsumgebungen upgraden.
Schritte vor dem Upgrade
- Führen Sie
composer outdatedaus und aktualisieren Sie alle Abhängigkeiten auf Versionen mit deklarierter PHP 8.3-Kompatibilität. - Führen Sie
php -d error_reporting=E_ALL your_app_entrypoint.phpunter PHP 8.3 CLI aus, um Deprecation-Hinweise zu erkennen, bevor sie zu fatalen Fehlern werden. - Prüfen Sie jeden Code, der
str_contains(),str_starts_with()oderstr_ends_with()mit Nicht-String-Argumenten aufruft — diese werfen jetztTypeErrorin strikten Kontexten. - Überprüfen Sie alle Klassenkonstanten, die Kindklassen überschreiben — typisierte Konstanten verursachen fatale Fehler, wenn Typen inkompatibel sind.
- Prüfen Sie die
phpinfo()-Ausgabe nach dem Upgrade, um zu bestätigen, dass OPcache und JIT mit der erwarteten Konfiguration aktiv sind.
php.ini-Optimierung für PHP 8.3-Produktion
; Recommended production baseline for PHP 8.3
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.jit=tracing
opcache.jit_buffer_size=64MDas Setzen von validate_timestamps=0 deaktiviert Dateiänderungsprüfungen bei jeder Anfrage — wesentlich für Hochlast-Deployments, bei denen der OPcache-Invalidierungs-Overhead messbar ist. Verwenden Sie stattdessen Deployment-Hooks, um opcache_reset() nach Code-Deployments aufzurufen.
Validierung nach dem Upgrade
# Verify active PHP version
php -v
# Confirm JIT is compiled in and active
php -r "var_dump(opcache_get_status()['jit']);"
# Check for deprecation notices in error log
tail -f /var/log/php-fpm/error.log | grep -i deprecatPHP 8.3 und Sicherheitsüberlegungen für Webanwendungen
PHP 8.3 führt keine neuen Sicherheitsprimitive ein, aber mehrere Änderungen haben indirekte Sicherheitsauswirkungen:
json_validate()reduziert die Angriffsfläche in Eingabevalidierungs-Pipelines, indem verhindert wird, dass fehlerhafte JSON-Daten die Deserialisierungslogik erreichen.- Typisierte Klassenkonstanten verhindern Typverwechslungsangriffe, bei denen eine Unterklasse einen unerwarteten Typ für eine sicherheitsrelevante Konstante substituiert (z. B. eine Berechtigungsstufe oder einen Timeout-Wert).
- Das
#[Override]-Attribut verhindert stilles Method-Shadowing in sicherheitskritischen Basisklassen, ein Vektor für subtile Privilege-Escalation-Bugs in Plugin-Architekturen. RandomRandomizer-Ergänzungen ersetzen unsichere Muster wiesubstr(str_shuffle(implode(range('a','z'))), 0, 16)für die Token-Generierung.
Für Anwendungen, die sensible Daten verarbeiten, ist die Kombination von PHP 8.3 mit einem korrekt konfigurierten TLS-Stack unverhandelbar. Wenn Ihre Hosting-Umgebung noch keine aktuellen SSL-Zertifikate eingesetzt hat, beheben Sie das vor jedem PHP-Upgrade.
Die richtige Hosting-Umgebung für PHP 8.3 wählen
Der JIT-Compiler von PHP 8.3 und die erhöhten Speicheranforderungen für die Auflösung typisierter Konstanten bedeuten, dass ressourcenbeschränkte Umgebungen möglicherweise nicht vollständig vom Upgrade profitieren.
- Shared Hosting: Die PHP-Versionsverfügbarkeit hängt vollständig vom Anbieter ab. Wenn Sie PHP 8.3 sofort benötigen, bieten Shared Web Hosting-Pläne mit PHP-Versionswechsel Flexibilität ohne Server-Management-Overhead.
- VPS: Volle Kontrolle über
php.ini, PHP-FPM-Pool-Konfiguration, OPcache-Optimierung und JIT-Buffer-Größe. Dies ist die empfohlene Mindestumgebung für PHP 8.3-Produktions-Deployments mit aktiviertem JIT. - Dedicated Server: Erforderlich für Hochlast-Anwendungen, bei denen JIT-Buffer-Konflikte über mehrere PHP-FPM-Worker hinweg zum Engpass werden. Eine dedizierte Umgebung ermöglicht auch NUMA-bewusste Speicherzuweisung für OPcache.
- GPU Hosting: Relevant, wenn Ihre PHP-Anwendung GPU-beschleunigte Workloads orchestriert (z. B. Python-ML-Inferenzdienste aufruft). GPU Hosting-Umgebungen profitieren von PHPs 8.3 verbessertem FFI und Prozessmanagement.
Wichtigste technische Erkenntnisse und Entscheidungsmatrix
Verwenden Sie typisierte Klassenkonstanten sofort, wenn:
- Ihre Codebasis Interfaces oder abstrakte Klassen mit Konstanten verwendet, die Kindklassen überschreiben.
- Sie PHPStan Level 8 oder Psalm verwenden — typisierte Konstanten ermöglichen strengere Analyse.
Aktivieren Sie JIT, wenn:
- Ihr Profiler zeigt, dass die CPU-Zeit mehr als 40% der Anforderungszeit übersteigt.
- Sie Batch-Verarbeitung, Datentransformation oder mathematische Workloads in PHP ausführen.
- Sie mindestens 64 MB dedizierten OPcache-JIT-Buffer pro PHP-FPM-Pool verfügbar haben.
Aktivieren Sie JIT nicht, wenn:
- Ihre Anwendung I/O-gebunden ist (Datenbank, Cache, Dateisystem, API-Aufrufe dominieren die Latenz).
- Sie auf Shared Hosting mit begrenztem OPcache-Speicher sind.
- Sie Ihre spezifische Workload nicht benchmarkt haben — nehmen Sie nichts an.
Verwenden Sie json_validate(), wenn:
- Sie JSON vor dem Dekodieren irgendwo in Ihrer Codebasis validieren.
- Sie hochvolumige Webhook- oder Message-Queue-Payloads verarbeiten.
Fügen Sie #[Override] hinzu zu:
- Jeder Methode in einer Kindklasse, die absichtlich eine Elternmethode überschreibt.
- Sicherheitskritischen Methoden-Überschreibungen in Plugin- oder Erweiterungsarchitekturen.
Migrieren Sie zu RandomRandomizer, wenn:
- Irgendein Teil Ihres Codes
rand(),mt_rand(),array_rand()oderstr_shuffle()für sicherheitssensitive Token- oder Schlüsselgenerierung verwendet.
FAQ
Bricht PHP 8.3 die Abwärtskompatibilität mit PHP 8.2-Code?
In den meisten Fällen nein. PHP 8.3 ist ein Minor-Release ohne entfernte Funktionen aus der Standardbibliothek, die nicht bereits in 8.2 veraltet waren. Jedoch werden neu veraltete Verhaltensweisen E_DEPRECATED-Hinweise ausgeben, und jeder Code, der sich auf implizite Typumwandlung in Konstanten oder range() mit Float-Schritten verlässt, kann sich anders verhalten. Führen Sie immer Ihre Testsuite unter PHP 8.3 aus, bevor Sie deployen.
Ist JIT standardmäßig in PHP 8.3 aktiviert?
Nein. JIT erfordert, dass OPcache aktiviert ist und opcache.jit_buffer_size auf einen Wert ungleich null gesetzt ist. Die Standard-php.ini, die mit den meisten Distributionen ausgeliefert wird, setzt opcache.jit_buffer_size=0, was JIT effektiv deaktiviert. Sie müssen es explizit konfigurieren.
Kann ich typisierte Klassenkonstanten mit Union-Typen in PHP 8.3 verwenden?
Ja. const int|string VERSION = 8; ist gültig. Intersection-Typen sind auch für Konstanten mit Objekttypen erlaubt. Die einzigen verbotenen Typen sind void und never.
Was ist der Unterschied zwischen json_validate() und json_decode() für Validierungszwecke?
json_validate() parst die JSON-Struktur, ohne einen PHP-Wert im Speicher zu konstruieren. Es ist für große Payloads deutlich speichereffizienter und schneller, wenn Sie nur die strukturelle Gültigkeit bestätigen müssen. json_decode() muss verwendet werden, wenn Sie die dekodierten Daten tatsächlich benötigen — rufen Sie nicht beide nacheinander auf; rufen Sie json_validate() nur auf, wenn Sie beabsichtigen, das Ergebnis zu verwerfen.
Unterstützt PHP 8.3 Readonly-Klassen, die in PHP 8.2 eingeführt wurden?
Ja, und es erweitert sie. PHP 8.3 erlaubt die Neuzuweisung von Readonly-Properties innerhalb von __clone(), was die primäre Einschränkung von Readonly-Klassen in PHP 8.2 war. Dies macht unveränderliche Value-Object-Muster ohne Workarounds vollständig praktikabel.
