I'm trying to experiment with FFI, and ran into an issue with PHP's default configuration. Or at least I believe it's the default configuration; I'm using Ondre's PPAs for Ubuntu. Let me try and lay out the moving parts:
The default ini settings that are in play:
opcache.enable => On => On
opcache.enable_cli => Off => Off
opcache.preload => no value => no value
ffi.enable => preload => preload
ffi.preload => no value => no value
That is, by default, FFI only works in preloaded files or on the cli. This makes sense.
Opcache is enabled by default. This makes sense.
Opcache is disabled by default on the CLI, since the whole engine shuts down after the command finishes so it wouldn't be cached anyway. This makes sense.
Because opcache is disabled for the CLI, the opcache.preload directive is ignored even if specified. This makes sense.
As near as I can tell from playing with it, using FFI::load() and FFI::scope() work only with preloading. Or at least, following the documentation I've not figured out how to get them to work otherwise.
So now, we have a default case where FFI (or some portion of it) only works with preloading, but opcache is disabled on the CLI, so preloading is diabled on the CLI, so FFI doesn't work out of the box. This... only makes sense after the fact but at the time makes no sense at all! And the error message you get is not at all helpful; it just throws an exception "Failed loading scope", which in no way indicates what the actual problem is.
The result is that, if coming from a default configuration, this example from the documentation fails mysteriously:
https://www.php.net/manual/en/ffi.examples-complete.php
The fix is simple enough: set opcache.enable_cli to true. It took me and another person in IRC over an hour to notice that, however. Let's not make anyone else go through that. :-)
I am not sure if there's something to be done about it other than adding the opcache.enable_cli line to the example linked above and documenting why it's needed. The defaults all make sense in themselves, but the result is broken in some circumstances. There may be other things that should be done as well; I'm not sure.
I defer to the list on how best to proceed here.
Addendum: The documentation for ffi.preload is completely unhelpful. I have no idea what file to put there or what it does. Can someone who understands that help improve the docs on it?
--
Larry Garfield
larry@garfieldtech.com