Signatur
Beschreibung
FFI\ParserException ist eine spezialisierte Ausnahme, die von der FFI-Extension geworfen wird, wenn der eingebettete C-Header-Parser auf einen Syntaxfehler oder eine ungültige Deklaration trifft. Sie tritt typischerweise auf, wenn an FFI::cdef() oder FFI::load() fehlerhafter oder nicht unterstützter C-Code übergeben wird.
Da FFI\ParserException \RuntimeException erweitert, kann sie wie jede andere PHP-Ausnahme mit einem try/catch-Block abgefangen werden. Dies erlaubt eine gezielte Fehlerbehandlung, wenn C-Header-Deklarationen zur Laufzeit dynamisch zusammengestellt werden.
Typische Ursachen sind: nicht unterstützte C-Schlüsselwörter (wie komplexe Präprozessor-Direktiven), Tippfehler in Typ- oder Funktionsdeklarationen, fehlende Semikolons oder ungültige Pointer-Syntax. Die Exception-Nachricht enthält in der Regel eine Beschreibung des Parserfehlers, die beim Debuggen hilfreich ist.
Diese Klasse hat keine eigenen Methoden oder Eigenschaften und nutzt vollständig die API von \RuntimeException (z. B. getMessage(), getCode(), getFile(), getLine()).
Beispiele
Syntaxfehler in C-Deklaration abfangen
<?php
try {
// Ungültige C-Deklaration: fehlendes Semikolon nach struct-Definition
$ffi = FFI::cdef("
struct Point {
int x
int y
};
");
} catch (\FFI\ParserException $e) {
echo 'C-Parser-Fehler: ' . $e->getMessage() . PHP_EOL;
echo 'In Datei: ' . $e->getFile() . ', Zeile: ' . $e->getLine() . PHP_EOL;
}
Dynamisch erzeugte Header-Deklaration validieren
<?php
function loadFfiSafely(string $cDefinition): ?FFI {
try {
return FFI::cdef($cDefinition);
} catch (\FFI\ParserException $e) {
error_log('Ungültige FFI-Deklaration: ' . $e->getMessage());
return null;
}
}
// Korrekte Deklaration
$ffi = loadFfiSafely('int abs(int j);');
if ($ffi !== null) {
echo $ffi->abs(-42) . PHP_EOL; // 42
}
// Fehlerhafte Deklaration
$ffi2 = loadFfiSafely('int @@ungültig@@(void);');
var_dump($ffi2); // NULL
// Wichtig · Fallstricke
Einschränkungen des C-Parsers: Die FFI-Extension verwendet einen eingeschränkten C-Parser, der keine vollständigen C-Präprozessor-Direktiven (wie #define, #include, #ifdef) unterstützt. Solche Direktiven müssen vor der Übergabe an FFI::cdef() entfernt oder durch tatsächliche Werte ersetzt werden, da sie sonst eine FFI\ParserException auslösen.
Unterschied zu FFI\Exception: Nicht alle FFI-Fehler führen zu einer FFI\ParserException. Laufzeitfehler (z. B. unbekannte Symbole in einer Bibliothek) werfen eine allgemeinere FFI\Exception. Es empfiehlt sich, beide Exceptions separat zu behandeln, wenn sowohl Parsing- als auch Laufzeitfehler erwartet werden.
Sicherheit: Übergeben Sie niemals ungeprüfte Benutzereingaben als C-Header-Deklaration an FFI-Funktionen, da dies zu beliebiger Code-Ausführung führen kann — unabhängig davon, ob eine FFI\ParserException ausgelöst wird oder nicht.