[PHP] PHP服务器接口SAPI中的结构体
SAPI:在各个服务器抽象层之间遵守着相同的约定,这里我们称之为SAPI接口。例如命令行程序的实现,Apache的mod_php模块实现以及fastcgi的实现等等
1.结构体:
使用结构体(Struct)来存放一组不同类型的数据
struct 结构体名{
结构体所包含的变量或数组
};
struct 结构体名 结构体变量名
2.成员的获取和赋值
结构体变量名.成员名;
3.结构体指针
struct 结构体名 *结构体变量名=&结构体变量名
使用结构体指针 ==> (*结构体变量名).成员名 ; 结构体变量名->成员名
PHP源码:
struct _sapi_module_struct {
char *name; // 名字(标识用)
char *pretty_name; // 更好理解的名字(自己翻译的)
int (*startup)(struct _sapi_module_struct *sapi_module); // 启动函数
int (*shutdown)(struct _sapi_module_struct *sapi_module); // 关闭方法
int (*activate)(TSRMLS_D); // 激活
int (*deactivate)(TSRMLS_D); // 停用
int (*ub_write)(const char *str, unsigned int str_length TSRMLS_DC);
// 不缓存的写操作(unbuffered write)
void (*flush)(void *server_context); // flush
struct stat *(*get_stat)(TSRMLS_D); // get uid
char *(*getenv)(char *name, size_t name_len TSRMLS_DC); // getenv
void (*sapi_error)(int type, const char *error_msg, ...); /* error handler */
int (*header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op,
sapi_headers_struct *sapi_headers TSRMLS_DC); /* header handler */
/* send headers handler */
int (*send_headers)(sapi_headers_struct *sapi_headers TSRMLS_DC);
void (*send_header)(sapi_header_struct *sapi_header,
void *server_context TSRMLS_DC); /* send header handler */
int (*read_post)(char *buffer, uint count_bytes TSRMLS_DC); /* read POST data */
char *(*read_cookies)(TSRMLS_D); /* read Cookies */
/* register server variables */
void (*register_server_variables)(zval *track_vars_array TSRMLS_DC);
void (*log_message)(char *message); /* Log message */
time_t (*get_request_time)(TSRMLS_D); /* Request Time */
void (*terminate_process)(TSRMLS_D); /* Child Terminate */
char *php_ini_path_override; // 覆盖的ini路径
...
...
};
cgi_sapi_module.startup(&cgi_sapi_module) // cgi模式 cgi/cgi_main.c文件
apache2_sapi_module.startup(&apache2_sapi_module);
// apache2服务器 apache2handler/sapi_apache2.c文件
static sapi_module_struct apache2_sapi_module = {
"apache2handler",
"Apache 2.0 Handler",
php_apache2_startup, /* startup */
php_module_shutdown_wrapper, /* shutdown */
...
}
startup 当SAPI初始化时,首先会调用该函数。如果服务器处理多个请求时,该函数只会调用一次。 比如Apache的SAPI,它是以mod_php5的Apache模块的形式加载到Apache中的, 在这个SAPI中,startup函数只在父进程中创建一次,在其fork的子进程中不会调用。
activate 此函数会在每个请求开始时调用,它会再次初始化每个请求前的数据结构。
deactivate 此函数会在每个请求结束时调用,它用来确保所有的数据都,以及释放在activate中初始化的数据结构。
shutdown 关闭函数,它用来释放所有的SAPI的数据结构、内存等。
ub_write 不缓存的写操作(unbuffered write),它是用来将PHP的数据输出给客户端, 如在CLI模式下,其最终是调用fwrite实现向标准输出输出内容;在Apache模块中,它最终是调用Apache提供的方法rwrite。
sapi_error 报告错误用,大多数的SAPI都是使用的PHP的默认实现php_error。
flush 刷新输出,在CLI模式下通过使用C语言的库函数fflush实现,在php_mode5模式下,使用Apache的提供的函数函数rflush实现。
read_cookie 在SAPI激活时,程序会调用此函数,并且将此函数获取的值赋值给SG(request_info).cookie_data。 在CLI模式下,此函数会返回NULL。
read_post 此函数和read_cookie一样也是在SAPI激活时调用,它与请求的方法相关,当请求的方法是POST时,程序会操作$_POST、$HTTP_RAW_POST_DATA等变量。
send_header 发送头部信息,此方法一般的SAPI都会定制,其所不同的是,有些的会调服务器自带的(如Apache),有些的需要你自己实现(如 FastCGI)。
我的练习:
#include <stdio.h>
int hello(int a){
return a+;
}
int main(){
//定义结构体
struct stu{
char *name;
int age;
int (*sum)(int);
};
//1.赋值结构体
struct stu student;
student.age=;
student.name="taoshihan";
student.sum=hello;
//使用结构体成员
printf("%d \n",student.sum()); //2.另一种赋值结构体方式
struct stu lstudent={
"taoshihan",
,
.sum=hello
};
printf("%s \n",lstudent.name);
printf("%d \n",lstudent.sum()); //3.结构体指针
struct stu *rstudent=&student;
//使用结构体指针
printf("%s \n",(*rstudent).name);
printf("%s \n",rstudent->name); //定义函数指针
int (*h)(int)=hello;
//使用函数指针
printf("%d \n",(*h)());
}
[PHP] PHP服务器接口SAPI中的结构体的更多相关文章
- 浅析C#中的结构体和类
类和结构是 .NET Framework 中的常规类型系统的两种基本构造. 两者在本质上都属于数据结构.封装着一组总体作为一个逻辑单位的数据和行为. 数据和行为是该类或结构的"成员" ...
- [转]C#中的结构体与类的区别
C#中的结构体与类的区别 经常听到有朋友在讨论C#中的结构与类有什么区别.正好这几日闲来无事,自己总结一下,希望大家指点. 1. 首先是语法定义上的区别啦,这个就不用多说了.定义类使用关键字cla ...
- C++中的结构体
http://zhidao.baidu.com/link?url=8OYQSKV9mvSBc6Hkf9NsLQmipSge9VCZDJQGAZZs5PCBQ54UTmK98VRmAklEEAFYu7d ...
- C/C++中的结构体
结构体定义 结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构. 结构体作用 结构体和其他类型基础数据类型一样,例如int类型,char类型 只不过结构体可以做成 ...
- C语言中的结构体,结构体数组
C语言中的结构体是一个小难点,下面我们详细来讲一下:至于什么是结构体,结构体为什么会产生,我就不说了,原因很简单,但是要注意到是结构体也是连续存储的,但要注意的是结构体里面类型各异,所以必然会产生内存 ...
- 再识C中的结构体
在前面认识C中的结构体中我介绍了结构体的基础知识,下面通过这段代码来回顾一下: #include<stdio.h> #define LEN 20 struct Student{ //定义结 ...
- C语言中的结构体和C++中的结构体以及C++中类的区别
c++中结构体可以定义一个函数 C中的结构体和C++中结构体的不同之处:在C中的结构体只能自定义数据类型,结构体中不允许有函数,而C++中的结构体可以加入成员函数. C++中的结构体和类的异同: 一. ...
- 关于C语言中结构体中的结构体成员导致的字节对齐问题
关于结构体的字节对齐是什么,就不赘述,再此附上一篇文章,介绍字节对齐:http://www.linuxsong.org/2010/09/c-byte-alignment/ 这里的结构体字节对齐的数据类 ...
- C语言中处理结构体的原理
汇编中有几种寻址方式,分别是直接寻址:(ds:[idata]).寄存器间接寻址(ds:[bx]).寄存器相对寻址(ds:[bx + idata].ds:[bx + si])基址变址寻址(ds:[bx ...
随机推荐
- 【功能代码】---4用JS获取地址栏参数方法
用JS获取地址栏参数方法 // 方法一:采用正则表达式获取地址栏参数:( 强烈推荐,既实用又方便!) function GetQueryString(name) { var reg = new Reg ...
- C++11 新知识点
翻了下新版的C++ Primer,新的C++ 11真是变化很大,新增了很多语法特性.虽然已经很久没在写C++了,但一直对这门经典语言很感兴趣的,大致看了看前几章基础部分,总结下新特性备个忘吧.估计也很 ...
- iOS js oc相互调用JavaScriptCore(一)
原址:http://blog.csdn.net/lwjok2007/article/details/47058101 1.普通调用 从iOS7开始 苹果公布了JavaScriptCore.framew ...
- Linux权限分析
我看过网上的一些有关Linux的权限分析,有些说的不够清楚,另外一些说的又太复杂.这里我尽量简单.清楚的把Linux权限问题阐述明白,Linux权限没有那么复杂. Linux权限问题要区分文件权限和目 ...
- 一口一口吃掉Volley(四)
欢迎访问我的个人博客转发请注明出处:http://www.wensibo.top/2017/02/17/一口一口吃掉Volley(四)/ 非常感谢你能够坚持看到第四篇,同时这也是这个Volley系列教 ...
- ES6 函数的扩展2
8.2 rest参数 ES6引入rest参数(形式为"-变量名"),用于获取函数的多余参数,这样就不需要使用arguments对象了. arguments对象并没有数组的方法,re ...
- IT小白学习Discuz!框架(一)
1.Discuz!是什么? 答:(1).Crossday Discuz! Board(简称 Discuz!)是北京康盛新创科技有限责任公司推出的一套通用的社区论坛软件系统. (2).Crossday ...
- 跟我一起学JQuery插件开发教程
在逛codeproject网站的时候,突然看到一篇文章:How to write plugin in Jquery. 如果对E文好的同学 ,可以看上面的连接.现在我把上面网站的及结合自己的想法写这篇文 ...
- python 模块:xlrd && xlwt
主要来自:http://www.jb51.net/article/60510.htm python读excel--xlrd 这个过程有几个比较麻烦的问题,比如读取日期.读合并单元格内容.下面先看看基本 ...
- css中的 nav ul li ul 与 nav>ul>li 这两种写法的区别
<nav> <ul id="a"> <li>a1</li> <li>a2</li> <li>a3 ...