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. IntelliJ IDEA创建java项目

    IntelliJ IDEA创建java项目 进入到IntelliJ IDEA启动界面,点击Create New Project 2.这样就进入到了创建项目页面,这里可以创建好多项目,这里我们以java ...

  2. [.Net跨平台]部署DTCMS到Jexus遇到的问题及解决思路--验证码

    上一篇博客我们已经基本完成了部署工作,目前发现了验证码出现500错误,分析其代码,我们可以看到验证码使用的是System.Drawing命名空间下的类库, GDI+ 位图,这个在肯定是平台相关的,所以 ...

  3. 【java】读取资源文件key->value,java.util.ResourceBundle

    package 国际化; import java.util.ResourceBundle; public class TestResource { public static void main(St ...

  4. 串String(2):串的实现(堆分配存储表示法)

    7/27/2017,先占个位,最近事情比较忙,明天敲一波代码,预测在一星期内搞定 9/02/2017,看到这个十分汗颜,八月去美帝学习了,没有抽空补上这一博文,计划这个月开了数据结构课后补上

  5. 浅析c++和c语言的enum类型

    1.先看c语言枚举类型 1.c语言定义枚举类型,每一个枚举元素都是一个整数2.注重数据类型,没有数据类型限定3.相邻枚举元素相差整数4.可以通过整数访问,不够安全 2.上代码: 1 #include& ...

  6. Linux第六节随笔 输入输出重定向 、管道、通配符、wc / grep / tr / sort / cut / which /whereis /locate /find /

    三期第五讲 -高级文件管理1.输入输出重定向 ls -l /dev/stdin -> /proc/self/fd/0 标准输入 设备:键盘 标记:0 ls -l /dev/stdout -> ...

  7. 学习Object.assign()

    Object.assign()用于将所有可枚举的值从一个或多个源对象复制到目标对象.它将返回目标对象. 语法 Object.assign(target, ...source); var obj = { ...

  8. c# 了解c# 面向对象

    C#是微软公司发布的一种面向对象的.运行于.NET Framework之上的高级程序设计语言.并定于在微软职业开发者论坛(PDC)上登台亮相.C#是微软公司研究员Anders Hejlsberg的最新 ...

  9. Generation Axe 吉他之夜音乐会-广州站 感受

    本人第一次看音乐会,演唱会跟音乐会是有区别的哈,演唱会以表演.舞蹈.歌唱为主,还有很多特别嘉宾 演出时间: 从20点开始一直到23点多才结束,有五个吉他手,开场跟结束五个吉他手一齐演出.平均每个人表演 ...

  10. Python第二十二天 stat模块 os.chmod方法 os.stat方法 pwd grp模块

    Python第二十二天   stat模块  os.chmod方法  os.stat方法  pwd  grp模块 stat模块描述了os.stat(filename)返回的文件属性列表中各值的意义,根据 ...