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中的结构体的更多相关文章

  1. 浅析C#中的结构体和类

    类和结构是 .NET Framework 中的常规类型系统的两种基本构造. 两者在本质上都属于数据结构.封装着一组总体作为一个逻辑单位的数据和行为. 数据和行为是该类或结构的"成员" ...

  2. [转]C#中的结构体与类的区别

    C#中的结构体与类的区别   经常听到有朋友在讨论C#中的结构与类有什么区别.正好这几日闲来无事,自己总结一下,希望大家指点. 1. 首先是语法定义上的区别啦,这个就不用多说了.定义类使用关键字cla ...

  3. C++中的结构体

    http://zhidao.baidu.com/link?url=8OYQSKV9mvSBc6Hkf9NsLQmipSge9VCZDJQGAZZs5PCBQ54UTmK98VRmAklEEAFYu7d ...

  4. C/C++中的结构体

    结构体定义 结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构.   结构体作用 结构体和其他类型基础数据类型一样,例如int类型,char类型 只不过结构体可以做成 ...

  5. C语言中的结构体,结构体数组

    C语言中的结构体是一个小难点,下面我们详细来讲一下:至于什么是结构体,结构体为什么会产生,我就不说了,原因很简单,但是要注意到是结构体也是连续存储的,但要注意的是结构体里面类型各异,所以必然会产生内存 ...

  6. 再识C中的结构体

    在前面认识C中的结构体中我介绍了结构体的基础知识,下面通过这段代码来回顾一下: #include<stdio.h> #define LEN 20 struct Student{ //定义结 ...

  7. C语言中的结构体和C++中的结构体以及C++中类的区别

    c++中结构体可以定义一个函数 C中的结构体和C++中结构体的不同之处:在C中的结构体只能自定义数据类型,结构体中不允许有函数,而C++中的结构体可以加入成员函数. C++中的结构体和类的异同: 一. ...

  8. 关于C语言中结构体中的结构体成员导致的字节对齐问题

    关于结构体的字节对齐是什么,就不赘述,再此附上一篇文章,介绍字节对齐:http://www.linuxsong.org/2010/09/c-byte-alignment/ 这里的结构体字节对齐的数据类 ...

  9. C语言中处理结构体的原理

    汇编中有几种寻址方式,分别是直接寻址:(ds:[idata]).寄存器间接寻址(ds:[bx]).寄存器相对寻址(ds:[bx + idata].ds:[bx + si])基址变址寻址(ds:[bx ...

随机推荐

  1. python串口调试,M3650B-HA调试

    使用python serial与M3650B-HA(RFID读写器)串口通信 环境:py3.6 模块:pyserial 1.serial模块安装2.废话不多说,直接上代码,测试环境py3.6 # co ...

  2. MySQL相关命令

    我们现在初步学习MySQL,下面来简单介绍一下MySQL常用命令 版权归skylinelin所有,转载请注明出处. 首先登录MySQL数据库,"\h"一下看一下帮助信息 这些就是M ...

  3. iOS 使用 CATransform3D 处理 3D 影像、制做互动立体旋转的效果

    1. Swift http://www.cocoachina.com/swift/20170518/19305.html domehttps://pan.baidu.com/s/1i4XXSkH OC ...

  4. iOS屏幕适配(尺寸适配)

    屏幕尺寸适配:一 在.pch中加入以下代码,在定义每个尺寸值的时候都调用下边的宏 //以iphone7为例 定义 view相关的宽高宏#define IPHONEHIGHT(b) [UIScreen ...

  5. PXE搭建

    前提最好是防火墙规则-F,关闭,selinux 是disable 这个在以后更新linux系统的时候还可以在这个基础上再次增加可以一体化安装的系统. 1.用yum来安装所需要的软件包,先来搭建yum光 ...

  6. 51Nod1203 2012集训队答辩 JZPLCM

    A1339. JZPLCM(顾昱洲) 时间限制:3.0s   内存限制:256.0MB   试题来源 2012中国国家集训队命题答辩 问题描述 给定一长度为n的正整数序列a,有q次询问,每次询问一段区 ...

  7. windows 下的python 安装pycrypto

    一般在官方网站下载pycrypto: https://www.dlitz.net/software/pycrypto/   然后使用命令就可以安装成功了: python setup.py build  ...

  8. 如何配置FTP服务器,方便操作服务器文件

    1 进入"控制面板"->"程序"->"打开或关闭Windows功能",找到"Internet信息服务"选项 ...

  9. eclipse在debug模式下总是自动进入到ThreadPoolExecutor类中

    当我们将web项目发布到tomcat服务器中,并且以debug模式启动的时候,总是自动跳转到 ThreadPoolExecutor 类中,如下: 解决办法 在eclipse中点击Window-> ...

  10. js 向form表单中插入数据

    var newElement = document.createElement("input"); var nowtime=year+""+month+day+ ...