Hello internals!
I have almost completed a SAPI, that allows NodeJS scripters to enable PHP from within their HTTP servers.
Originally, I wanted to write this extension just for my own use, but as I see the many „dirty“ hacks that people use to run PHP inside their http server, I decided to make this extension more available, once its done and working.
However, the build process is a bit complicated, as it plays between worlds; the autoconf based PHP build system and the GYP driven node extension build system. So far, I am working on the first solution: Building the extension using PHP’s build mechanism.
As I know the procedure for building nodejs addons by their commands, I’d just need to add a custom action/rule to the build, that builds a static library/bundle with .node as file extension isntead of the usual .so/.dll.
How do I do that? Its two C++ files (tinythread.cpp, v8php.cc) that need to be compiled. v8php.cc houses the entire SAPI code as well as the nodejs bindings.
And as a side note: When the user has previously built PHP with ZTS and Embed-SAPI, so that libphp5 is built, can they just link a SAPI against that? I see that php-config lists the SAPIs, and I wondered if there is a generated file that lists/depends on all the SAPIs.
Kind regards,
Ingwie
Op 03-08-14 om 02:24 schreef Ingwie Phoenix:
Hello internals!
I have almost completed a SAPI, that allows NodeJS scripters to enable PHP from within their HTTP servers.
Originally, I wanted to write this extension just for my own use, but as I see the many „dirty“ hacks that people use to run PHP inside their http server, I decided to make this extension more available, once its done and working.
If "dirty" means that each different HTTP server needs a SAPI with very
specific code for that HTTP server and often the first iteration of such
a SAPI is done by modifying the embed SAPI to suit the HTTP server's
specifics, then "dirty" is kind of logical and inevitable. The lack of
online documentation about the internals make people often "butcher" an
existing SAPI to fit their needs.
Each HTTP server has its own way of dealing with exchanging data
structures for incoming and outgoing HTTP headers, cookies, URL to "file
object & GET variables" parsing, POST data, etc. That's why PHP has the
sapi_module_struct which allows you to interface between PHP and your
HTTP server by use of attaching callback functions for the items you
wish to integrate. Basically each SAPI is an implementation of those
callback functions. The official Embed and my Embed2 project you
evaluated are different beasts. They are not meant to integrate with a
HTTP server but with applications desiring to allow PHP scripts in a non
web server context. They allow you to go in and out of PHP execution
context and mix with C / C++ code without actually dealing with a single
isolated PHP script run. Of course they can be used to start a new SAPI
for a specifically flavored HTTP server but they do add boilerplate not
needed if only desiring the integrate with a "regular" HTTP server.
However, the build process is a bit complicated, as it plays between worlds; the autoconf based PHP build system and the GYP driven node extension build system. So far, I am working on the first solution: Building the extension using PHP’s build mechanism.
As I know the procedure for building nodejs addons by their commands, I’d just need to add a custom action/rule to the build, that builds a static library/bundle with .node as file extension isntead of the usual .so/.dll.
How do I do that? Its two C++ files (tinythread.cpp, v8php.cc) that need to be compiled. v8php.cc houses the entire SAPI code as well as the nodejs bindings.
And as a side note: When the user has previously built PHP with ZTS and Embed-SAPI, so that libphp5 is built, can they just link a SAPI against that? I see that php-config lists the SAPIs, and I wondered if there is a generated file that lists/depends on all the SAPIs.
See my above comment on SAPI's. Basically once a libphp5 has been built,
it has implementations (or not) for the various integration touch points
(send_headers, read_post, read_cookies, etc.). The libphp5 is a library
with the user selected SAPI implemented. So to answer your question, no
you can't link another SAPI against it and you've asked the wrong
question. It seems you treat SAPIs as if they are regular PHP extensions
you should add them after a PHP build. They are not and you should also
treat them differently.
You have two choices. Add the integration code on the PHP project end or
the HTTP Server project end. The majority of SAPI's do the integration
piece on the PHP end and I suggest you do the same for your integration.
If you wish to go the other route you could build an extremely bare bone
PHP SAPI wrapper that implements nothing and leave the implementation
details of the sapi_module_struct and php initialization to the HTTP
Server project piece.
The best way to build a PHP Library with your own SAPI is to make sure
you've implemented the config.m4 and config.w32 files, add the SAPI
project to the PHP source tree under the sapi directory and run
./buildconf --force to generate configure files including the option to
build your SAPI. Now you can build your libphp5 library with your SAPI
flavor in the same way as the other SAPIs.
Kind regards,
Ingwie
kind regards,
Bas van Beek