Alexander Lisachenko hat einen RFC-Vorschlag zur Erweiterung von PHPs Foreign Function Interface (FFI) mit optionaler Abbildung von C-Struct-Typen auf Benutzerlandklassen eingereicht.

Die aktuelle FFI-Implementierung kapselt alle C-Werte – Strings, Objekte, primitive Zeiger – in einer einzigen finalen Klasse FFI\CData. Dieser einheitliche Typ erhält Flexibilität, verhindert aber, dass statische Analysetools und IDEs Struct-Felder typ-prüfen können, und instanceof-Operationen funktionieren nicht auf abgebildeten Typen. FFI-Bindungsgeneratoren umgehen diese Einschränkung derzeit, indem sie Stub-Klassen, IDE-Metadatendateien und Analyzer-Plugins ausliefern, doch das Ergebnis bleibt schwächer als native Unterstützung.

Lisachenkos Vorschlag führt ein Options-Array in FFI::cdef() ein, das eine Klassenabbildungskonfiguration akzeptiert und C-Typnamen auf PHP-Klassennamen abbildet:

```php $ffi = FFI::cdef($code, $lib, options: [ 'classmap' => [ 'zend_string' => \My\Engine\ZendString::class, ], ]); ```

Wenn ein Typ registriert ist, wird jedes FFI-Handle, das dafür erstellt wird – von FFI::new(), FFI::cast(), Struct-Feldlesevorgängen oder Funktionsrückgaben – eine Instanz der abgebildeten Klasse. Dies ermöglicht, dass get_class() den richtigen Typ zurückgibt, instanceof-Überprüfungen funktionieren und native Parameter- und Rückgabetypen vom Engine erzwungen werden.

Die Implementierung bleibt lokal in ext/ffi mit Zero Overhead, wenn sie nicht verwendet wird. Der Objektspeicher bleibt die gleiche zend_ffi_cdata-Struktur mit gemeinsamen Handlern; nur der Klasseneintrag-Zeiger ändert sich. Die einzige Breaking Change ist, dass FFI\CData für registrierte Klassen erweiterbar wird. Alle Änderungen sind rückwärtskompatibel und optional aktivierbar.

Der Vorschlag erwähnt auch optionale Typmap für benutzerdefinierte Marshalling-Callbacks (from_cdata/to_cdata), wobei der Autor Rückmeldungen dazu sucht, ob diese Funktion in einer ersten Iteration enthalten sein soll.

Lisachenko betreut das z-engine-Framework, das diese Semantik bereits im Userland emuliert und eine reale Testumgebung bietet. Er zielt auf PHP 8.6 ab und bietet an, die Funktion zu implementieren, wenn das Feedback positiv ausfällt.