PHP7源码分析(php7.0.17)----Embed
2018-01-13 19:05
573 查看
SAPI是PHP框架的接口层,它是进入PHP内部的入口。PHP中实现的SAPI有很多,比较典型的有:CLI、FPM、Embed、Apache2handler、Cgi、Phpdbg、litespeed。
Embed
如果我们在自己的第三方程序中也想使用PHP,那怎么办?PHP提供了一个用于这类应用场景下的SAPI,那就是Embed,它在编译后就是普通的库文件(可以选择编译为静态库或共享库),我们可以在其他的C/C++应用中调用PHP提供的API。
编译PHP时通过–enable-embed=[shared|static]指定库类型,默认共享库,编译完成后可以在PHP安装位置的/lib目录下看到生产的库文件,同时在include/php/sapi目录下会生产一个存放Embed头文件的目录。
实现
首先我们来看一下Embed的实现,实际它的逻辑非常简单,只是把PHP生命周期的几个处理函数进行了封装,它对外提供了两个API。
php_embed_init()
php_embed_shutdown()
与php_embed_init()对应,主要完成PHP框架的关闭收尾工作
使用
下面我们举个例子具体看一下如何在一个C程序中嵌入PHP,使用的是共享库,这个例子中我们定义的C程序将调用PHP完成一个普通PHP脚本的执行。
定义完成后编译,编译时需要通过-I指定PHP的头文件目录,包括PHP、Zend、SAPI、TSRM的,通过-I以及-L 指定共享库的目录和名称。另外。还需要通过-rpath指定运行时共享库的位置。假如PHP安装路径为/usr/local/webserver/php,则编译参数为
编译后执行
Embed
如果我们在自己的第三方程序中也想使用PHP,那怎么办?PHP提供了一个用于这类应用场景下的SAPI,那就是Embed,它在编译后就是普通的库文件(可以选择编译为静态库或共享库),我们可以在其他的C/C++应用中调用PHP提供的API。
编译PHP时通过–enable-embed=[shared|static]指定库类型,默认共享库,编译完成后可以在PHP安装位置的/lib目录下看到生产的库文件,同时在include/php/sapi目录下会生产一个存放Embed头文件的目录。
'./configure' '--prefix=/usr/local/webserver/php' \ '--with-config-file-path=/usr/local/webserver/php/etc' \ '--enable-fpm' '--with-fpm-user=oae' '--with-fpm-group=oae'\ '--with-mysqli' '--with-pdo-mysql' \ '--with-iconv-dir' '--with-freetype-dir' '--with-jpeg-dir' '--with-png-dir' \ '--with-zlib' '--with-libxml-dir=/usr' '--enable-xml' '--disable-rpath' \ '--enable-bcmath' '--enable-shmop' '--enable-sysvsem' \ '--enable-inline-optimization' '--with-curl' \ '--enable-mbregex' '--enable-mbstring' '--with-mcrypt' \ '--enable-ftp' '--with-gd' '--enable-gd-native-ttf' \ '--with-openssl' '--with-mhash' '--enable-pcntl' \ '--enable-sockets' '--with-xmlrpc' '--enable-zip' \ '--enable-soap' '--without-pear' '--with-gettext' \ '--enable-fileinfo' '--enable-maintainer-zts' \ --enable-embed=shared
实现
首先我们来看一下Embed的实现,实际它的逻辑非常简单,只是把PHP生命周期的几个处理函数进行了封装,它对外提供了两个API。
php_embed_init()
EMBED_SAPI_API int php_embed_init(int argc, char **argv) { zend_llist global_vars; …… #ifdef ZTS //启动SAPI tsrm_startup(1, 1, 0, NULL); (void)ts_resource(0); ZEND_TSRMLS_CACHE_UPDATE(); #endif #ifdef ZEND_SIGNALS zend_signal_startup(); #endif //初始化SAPI sapi_startup(&php_embed_module); …… //模块初始化阶段 if (php_embed_module.startup(&php_embed_module)==FAILURE) { return FAILURE; } …… SG(options) |= SAPI_OPTION_NO_CHDIR; SG(request_info).argc=argc; SG(request_info).argv=argv; //请求初始化阶段 if (php_request_startup()==FAILURE) { php_module_shutdown(); return FAILURE; } ……
php_embed_shutdown()
与php_embed_init()对应,主要完成PHP框架的关闭收尾工作
EMBED_SAPI_API void php_embed_shutdown(void) { //关闭请求,request shutdown阶段 php_request_shutdown((void *) 0); //关闭模块阶段 php_module_shutdown(); sapi_shutdown(); #ifdef ZTS tsrm_shutdown(); #endif if (php_embed_module.ini_entries) { free(php_embed_module.ini_entries); php_embed_module.ini_entries = NULL; } }
使用
下面我们举个例子具体看一下如何在一个C程序中嵌入PHP,使用的是共享库,这个例子中我们定义的C程序将调用PHP完成一个普通PHP脚本的执行。
//my_main.c root@11792096ccc6:/home/oae/c/embed# vi my_main.c #include "/data/software/php7/sapi/embed/php_embed.h" int main(int argc, char **argv) { zend_file_handle file_handle; //PHP框架初始化 php_embed_init(argc,argv); file_handle.type = ZEND_HANDLE_FILENAME; file_handle.filename = "call.php"; //execute php script php_execute_script(&file_handle); //关闭PHP框架 php_embed_shutdown(); return 0; }
//call.php <?php function my_func($a,$b) { return $a+$b; } echo my_func(200,300)."\n"; ?>
定义完成后编译,编译时需要通过-I指定PHP的头文件目录,包括PHP、Zend、SAPI、TSRM的,通过-I以及-L 指定共享库的目录和名称。另外。还需要通过-rpath指定运行时共享库的位置。假如PHP安装路径为/usr/local/webserver/php,则编译参数为
gcc -o my_test my_main.c -I /usr/local/webserver/php/include/ \ -I /usr/local/webserver/php/include/php/ \ -I /usr/local/webserver/php/include/php/include/ \ -I /usr/local/webserver/php/include/php/main/ \ -I /usr/local/webserver/php/include/php/TSRM/ \ -I/usr/local/webserver/php/include/php/Zend/ \ -L /usr/local/webserver/php/lib/ \ -lphp -Wl,-rpath /usr/local/webserver/php/lib
编译后执行
./my_php 500
相关文章推荐
- DEDE源码分析与学习---index.php文件解读。
- CI框架源码完全分析之入口文件index.php
- CI框架源码完全分析之核心文件(模型)Model.php
- PHP源码分析-变量的存储方式
- Discuz! X2 核心类源码(class_core.php)分析
- php源码fpm分析
- ECSHOP 源码分析(includes/init.php)
- php源码分析之DZX1.5随机数函数random用法
- CI框架源码完全分析之核心文件URI.php
- 深入PHP购物车模块功能分析(函数讲解,附源码)
- CI框架源码完全分析之核心文件(钩子)Hooks.php
- phpcms 源码分析一: common.inc.php
- Magento源码分析笔录二:Mage.php主要枢纽类
- dvwa 源码分析(一) --- setup.php分析
- CI框架源码分析之Session类Session.php
- find_fufei.php源码分析
- ecshop源码分析--init.php
- PHP源码分析-数组
- CI框架源码完全分析之核心文件(路由)Router.php
- PHP源码分析-弱类型变量实现