PHP详解php
一个php实例,当被调用的时候,都会一次通过Module init,Request init,Request shutdown,Module shutdown四个过程.执行次数由SAPI(server abstraction API,服务器抽象化程序接口)来决定。数组
1)Call each extension's MINIT这个过程在载入的时候被调用安全
PHP_MINIT_FUNCTION(扩展名称){ /*注册常量或者初始化操做*/ return SUCCESS; }
2)Request服务器
PHP_RINT_FUNCTION(扩展名称){ /*处理请求*/ return SUCCESS; }
3)Execute函数
执行php阶段,主要是把PHP文件编译成Opcodes而后在php虚拟机下执行线程
ps:能够安装VLD扩展来查看php的opcode详细内容翻译
4)Call each extension's RESHUTDOWNcode
请求处理完进入结束状态,通常脚本执行到结尾,或者经过调用exit()或者die()函数PHP将进入结束状态,结束也分为两个环节,一个在请求后(RSHUTDOWN),一个在SAPI生命周期结束时候(MSHUTDOWN)server
PHP_RSHUTDOWN_FUNCTION{ return SUCCESS; } PHP_MSHUTDOWN_FUNCTION{ /*注销持久化资源*/ return SUCCESS; }
在请求一个php页面,php基本上按照这个流程来执行的。接口
ZEND引擎
Zend引擎是脚本语言引擎,主要工做是解析,翻译和执行php脚本,主要执行两个功能
当咱们执行./ext_skel --extname=扩展名称的时候活建立你的扩展名称.c文件
结构以下所示
#ifdef HAVE_CONFIG_H #include "config.h" #endif /** 包含头文件引入所需的配置文件API等**/ #include "php.h" /*在php扩展中,必须包含php.h头文件,它位于main目录下,这个文件包含构建扩展时必须的各类宏和API定义*/ #include "php_ini.h" #include "ext/standard/info.h" #include "php_php_list.h" /* True global resources - no need for thread safety here */ static int le_php_list; /*声明ZEND函数块*/ /*ZEND 引擎经过zend_function_entry 结构数组把声明的导出函数引入内部*/ const zend_function_entry php_list_functions[] = { PHP_FE(confirm_php_list_compiled, NULL) PHP_FE_END /*必须以PHP_FE_END结尾*/ /*早期的php是以{NULL,NULL,NULL}结尾,如今ZEND把这个和宏绑定在一块儿了*/ /* #define PHP_FE_END ZEND_FE_END #define ZEND_FE_END { NULL, NULL, NULL, 0, 0 } */ }; /*声明ZEND模块*/ zend_module_entry php_list_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif "php_list", php_list_functions, PHP_MINIT(php_list), PHP_MSHUTDOWN(php_list), PHP_RINIT(php_list), PHP_RSHUTDOWN(php_list), PHP_MINFO(php_list), #if ZEND_MODULE_API_NO >= 20010901 PHP_PHP_LIST_VERSION, #endif STANDARD_MODULE_PROPERTIES }; /*实现get_moudle()函数*/ #ifdef COMPILE_DL_PHP_LIST ZEND_GET_MODULE(php_list) #endif /*php的生命周期*/ PHP_MINIT_FUNCTION(php_list) { return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(php_list) { return SUCCESS; } PHP_RINIT_FUNCTION(php_list) { return SUCCESS; } PHP_RSHUTDOWN_FUNCTION(php_list) { return SUCCESS; } /*此处配置的是显示在phpinfo()扩展名下的内容*/ PHP_MINFO_FUNCTION(php_list) { php_info_print_table_start(); php_info_print_table_header(2,"first","second"); php_info_print_table_row(2,"mother","fucker"); php_info_print_table_row(2,"fill","fucker"); php_info_print_table_end(); } /*实现导出函数*/ PHP_FUNCTION(confirm_php_list_compiled) { char *str = NULL; //获取输入的个数 int argc = ZEND_NUM_ARGS(); int str_len; /* 字符串 长度*/ long n; char *result; char *ptr; int result_length; if(zend_parse_parameters(argc TSRMLS_CC,"sl",&str,&str_len,&n)==FAILURE) return ; //获取字符的总长度(字符串长度 * 重复次数) result_length = (str_len)*n; //分配空间 result = (char *) emalloc(result_length+1); ptr = result; while(n--){ memcpy(ptr,str,str_len); ptr+=str_len; } *ptr ='\0'; RETURN_STRINGL(result,result_length,0); }
取得用户传递的参数
php支持可变参数,能够使用ZEND_NUM_ARGS(传入参数的数量)宏实现,其实这个宏等于参数ht。
取得参数的实体
int zend_parse_parameters(int nums TSRMLS_CC,"char * type",....) /* 第一个参数 nums:表名要接受参数的个数 第二个参数 TSRMLS_CC:是否启用线程安全 第三个参数:指定传来参数的类型(字符串) 剩下的参数:根据第三个参数类型声明不一样的地址 注:字符串‘s’,须要使用两个变量来保存 */
待续....