Setting up the hosting environment
Now that you've learned about the Phpapi world, and you can do a lot of work using zval and the language internal extension mechanism, it's time to shift your target and use it to do what it does best: interpret the scripting code.
Embedded SAPI
In retrospect, PHP builds a hierarchical system. The highest level is all extensions that provide user-space functions and class libraries. At the same time, it is the service API (SAPI) layer, which acts as an interface to webserver (such as Apache, IIS, and command-line interface CLI).
In many SAPI implementations, a special SAPI is embedded SAPI. When this SAPI implementation is built, you will create a library object that contains all of the PHP and Zend API functions and variables you know, and this library object also contains additional help functions and macros to simplify calls to external programs.
The library and header files that generate the embedded APIs perform the same actions as other SAPI compilations. You only need to pass--enable-embed to the./configure command. As before, using--enable-debug is helpful for error reporting and tracking.
You may also need to open--enable-maintainer-zts, of course, for reasons you have already heard, and it will help you notice the error of the code, but there are other reasons. Suppose that at some point you have multiple applications that use PHP to embed a library to execute a script task; One application is a simple short lifecycle, and it doesn't use threads, so for efficiency you might want to close zts.
Now assume that the second application uses threads, such as webserver, that each thread needs to track its own request context. If the zts is closed, only the first application can use the library; However, if Zts is turned on, two applications can use the same shared object in their own process space.
Of course, you can also build two versions at the same time and give them different names, but this is more problematic than including the small efficiencies that ZTS brings when you don't need zts.
By default, an embedded library is built as a libphp5.so shared object, or a dynamic-link library under Windows, but it may also be constructed as a static library using the optional Static keyword (--enable-embed=static).
The version built as a static library avoids the problem of zts/Zts and the potential for multiple versions of PHP in a system. The risk is that this means that your results will be significantly larger with the binary, which will host the entire zendengine and PHP framework, so you need to carefully consider whether you need a relatively small library when choosing.
Whichever way you choose to build, once you execute make install, LIBPHP5 will be copied to the lib/directory in your./configure specified prefix directory. You will also put a header file named Php_embed.h in the prefix/include/php/sapi/embed directory and several other important headers that you need to compile your program using the PHP embedded library.
Build and compile a host application
In essence, a library is just a collection of code without purpose. In order for it to work, you need to embed PHP applications. First, we encapsulate a very simple application that starts the Zend engine and initializes PHP to process a request, and then goes back to the resource cleanup.
#include <sapi/embed/php_embed.h>
int main (int argc, char *argv[])
{
Php_embed_start_block (argc, argv)
Php_embed_end_block () return
0;
}
Since this involves a lot of header files, it actually takes longer to build than the amount of time it normally takes for such a small piece of code. If you use a prefix different from the default path (/usr/local), make sure that you specify the path in the following way:
Gcc-i/usr/local/php-dev/include/php/ \
-i/usr/local/php-dev/include/php/main/ \
-i/usr/local/ php-dev/include/php/zend/ \
-i/usr/local/php-dev/include/php/tsrm/ \
-lphp5 \
o Embed1
embed1.c
Since this command is cumbersome to input each time, you may prefer to use a simple makefile instead:
CC = gcc
cflags =-C
-i/usr/local/php-dev/include/php/ \
-i/usr/local/php-dev/include/php/main / \
-i/usr/local/php-dev/include/php/zend/ \
-i/usr/local/php-dev/include/php/tsrm/ \
-wall-g \
ldflags =-lphp5
all:embed1.c
$ (cc)-O embed1.o embed1.c $ (cflags)
$ (cc)-O Embed1 EMBED1.O $ (ldflags)
There are some important differences between this makefile and the commands provided earlier. First, it opens the compile-time warning with the-wall switch, and the debug information is turned on with-G. In addition, it will compile and link the two phases into two separate phases, so it is relatively easy to add more source files later. Please group this makefile yourself, but the tab (Horizontal tab) instead of the space is used to align.
Now that you have made changes to the embed1.c source file, you can build a new embed1 executable by just executing a make command.