RE: [PHP-DEV] [RFC] Extension Prepend Files
| From: | François Laupretre | Date: | Tue, 06 Jan 2015 04:21:26 +0000 |
| Subject: | RE: [PHP-DEV] [RFC] Extension Prepend Files | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-80218@lists.php.net to get a copy of this message | ||
> -----Message d'origine-----
> De : php@golemon.com [mailto:php@golemon.com] De la part de Sara Golemon
>
> So, I've been meaning to propose something *like* this, but with a few
> key implementation detail differences:
>
> 1) Create the notion of "Persistent User Functions/Classes/Constants/etc
>
> 2) Embedded text sections
First, persistent PHP code or data (NOT reloading code for each request) is a huge can of worms. If
Sara decides to re-launch the idea, that will be great but the subject is probably out of scope
here.
IMHO, what we need here is a generic mechanism to embed PHP code in C extensions and, then, execute
it. It should define a way to embed PHP scripts as C strings at compile time, how to make these
scripts known and accessible from the PHP core, and how to execute them when needed.
Instead of including the runtime code in every extensions, as it is done in ext-embed, I would
prefer an extension which would provide this service to other 'client' extensions. It
would define a stream wrapper to access the registered PHP scripts. Script registration would be
registered in persistent memory during MINIT. The registration would return an ID for each
registered script. These IDs would be stored by the client extension and would be used to derive a
stream-wrapped path when the client decides to execute a registered script. These paths would
uniquely reference the scripts, which would allow to opcode-cache them.
As a specific case, if an extension wants to execute some PHP code at the beginning of each request,
it can execute its script(s) during RINIT, but it is just a use case of a more general mechanism.
RINIT execution order can be resolved using module dependencies.
Extending the mechanism to userspace 'plain file' scripts could be provided by a
'bridge'. The user could register a plain file script, whose content would be stored in
persistent memory, with a flag that would cause the script to be loaded during every RINIT.
One more word about executing scripts during every RINIT : even with opcode caches, as Sara notes,
the performance hit is not negligible. The question is always the same : What is the percentage of
requests that will really use the classes/functions we define there ? Remember that the list of
scripts is hardcoded in an extension. If the extension wants to allow conditional loading for
different features, it needs to define appropriate ini settings. Choosing the list of scripts at
compile time is another option but would make the distribution of precompiled binaries complex.
I personally favor another approach. I still use the PHK extension as an example of this
'intermediate' approach. This extension defines C-levels front-end classes. These classes
contain the 'fast' code. When this code needs to access 'slow' PHP code, it
executes the PHP scripts it needs, then calls the just-defined PHP classes. This way, we preserve
the possibility to code a big part of the extension in PHP, without the overhead of loading the PHP
code at the beginning of each request.
Thanks for your attention :)
François