
php内核分析之sapimodulestruct.docx
6页php 内核分析之 sapimodulestruct为了帮助同学们学习 PHP内核技术,了 php 内核分析之sapi_module_struct ,希望对大家有所帮助 ! 更多内容请关注 !这里阅读的 php 版本为 PHP-7.1.0RC3,阅读代码的平台为 linux 首先是寻找 php 的入口, php 有很多种模式, apache,php-fpm,cli 模式,我要入手的话,只能先从最简单的 cli 模型开始那么,我需要先寻找php-r'echo12;'这个命令是如何执行的首先还是寻找main入口,由于我们看的是命令行的php程序所以,这个入口在sapi/cli/php_cli.c中首先是定义一系列的变量intc;zend_file_handlefile_handle;intbehavior=PHP_MODE_STANDARD;char*reflection_what=NULL;volatileintrequest_started=0;volatileintexit_status=0;char*php_optarg=NULL,*orig_optarg=NULL;intphp_optind=1,orig_optind=1;char*exec_direct=NULL,*exec_run=NULL,*exec_begin=NULL,*exec_end=NULL;char*arg_free=NULL,**arg_excp=&arg_free;char*script_file=NULL,*translated_path=NULL;intinteractive=0;intlineno=0;constchar*param_error=NULL;inthide_argv=0;然后是这个sapi_module_struct*sapi_module=&cli_sapi_module;这是一个 sapi_module_struct 结构,这个结构是 sapi 中最重要的数据结构。
它的定义在 main/SAPI.h 中下面是增加了注释的代码:struct_sapi_module_struct{//SAPI 模块结构char*name;// 应用层名称,比如 cli,cgi 等char*pretty_name;// 应用层更易读的名字, 比如 cli 对应的就是 CommandLineInterfaceint(*startup)(struct_sapi_module_struct*sapi_module);// 当一个应用要调用 php 的时候,这个模块启动的时候会调用的函数int(*shutdown)(struct_sapi_module_struct*sapi_module);// 当一个应用要调用 php 的时候,这个模块结束的时候会调用的函数int(*activate)(void);// 在处理每个 request 的时候,激活需要调用的函数int(*deactivate)(void);// 在处理完每个 request 的时候,收尾时候要调用的函数size_t(*ub_write)(constchar*str,size_tstr_length);// 这个函数告诉 php 如何输出数据void(*flush)(void*server_context);// 提供给 php 的刷新缓存的函数指针zend_stat_t*(*get_stat)(void);// 用来判断要执行文件的权限,来判断是否有执行权限char*(*getenv)(char*name,size_tname_len);// 获取环境变量的方法void(*sapi_error)(inttype,constchar*error_msg,...)ZEND_ATTRIBUTE_FORMAT(printf,2,3);// 错误处理方法int(*header_handler)(sapi_header_struct*sapi_header,sapi_header_op_enumop,sapi_headers_struct*sapi_headers);// 这个函数会在我们调用 header() 的时候被调用int(*send_headers)(sapi_headers_struct*sapi_headers);// 发送所有的 headervoid(*send_header)(sapi_header_struct*sapi_header,void*server_context);// 单独发送某一个 headersize_t(*read_post)(char*buffer,size_tcount_bytes);// 如何获取 POST中的数据char*(*read_cookies)(void);// 如何获取 cookie 中的数据void(*register_server_variables)(zval*track_vars_array);//这个函数可以给 $_SERVER中获取变量void(*log_message)(char*message,intsyslog_type_int);//输出错误信息函数double(*get_request_time)(void);// 获取请求时间的函数void(*terminate_process)(void);//TODO: 调用 exit 的时候调用的方法char*php_ini_path_override;//PHP 的 ini 文件被复写了所复写的地址void(*default_post_reader)(void);// 这里和前面的read_post 有个差别, read_post 负责如何获取 POST数据,而这里的函数负责如何解析 POST数据void(*treat_data)(intarg,char*str,zval*destArray);// 对数据进行处理,比如进行安全过滤等。
default_post_reader/tread_data/input_filter 是三个能对输入进行过滤和处理的函数char*executable_location;// 执行的地理位置intphp_ini_ignore;// 是否不使用任何 ini 配置文件,比如php-n就将这个位置设置为1intphp_ini_ignore_cwd;//不在当前路径寻找php.iniint(*get_fd)(int*fd);//获取执行文件的fdint(*force__10)(void);//强制使用1.0int(*get_target_uid)(uid_t*);//获取执行程序的uidint(*get_target_gid)(gid_t*);//获取执行程序的gidunsignedint(*input_filter)(intarg,char*var,char**val,size_tval_len,size_t*new_val_len);// 对输入进行过滤比如将输入参数填充到自动全局变量 $_GET,$_POST,$_COOKIE中void(*ini_defaults)(HashTable*configuration_hash);// 默认的 ini 配置intphpinfo_as_text;// 是否打印 phpinfo 信息char*ini_entries;// 有没有附带的 ini 配置,比如使用php-ddate.timezone=America/Adak, 可以在命令行中设置时区constzend_function_entry*additional_functions;// 每个SAPI 模块特有的一些函数注册, 比如 cli 的 cli_get_process_titleunsignedint(*input_filter_init)(void);//TODO:};。












