美文网首页
php内核分析(1)sapi_module_struct

php内核分析(1)sapi_module_struct

作者: 奋斗live | 来源:发表于2019-04-17 10:59 被阅读0次
一、环境

centos7.2
php版本 7.0
如下


image.png
二、php模式

PHP具有apache、php-fpm、cli模式

三、找到cli模式的入口处

这里先学习cli模式
新建index.php,如下

<?php
echo "fff";
?>

使用gdb进行调试php,没安装gdb的要提前安装好,php也要提前编译好

gdb php
b main
run index.php

如下图


image.png
四、查看main

cli模式下的main在于 sapi/cli/php_cli.c文件中
如下图


image.png
五、cli_sapi_module变量

是通过sapi_module_struct结构体进行定义的
位于sapi/cli/php_cli.c文件中,如下定义

static sapi_module_struct cli_sapi_module = {
    "cli",                          /* name */
    "Command Line Interface",       /* pretty name */

    php_cli_startup,                /* startup */
    php_module_shutdown_wrapper,    /* shutdown */

    NULL,                           /* activate */
    sapi_cli_deactivate,            /* deactivate */

    sapi_cli_ub_write,              /* unbuffered write */
    sapi_cli_flush,                 /* flush */
    NULL,                           /* get uid */
    NULL,                           /* getenv */

    php_error,                      /* error handler */

    sapi_cli_header_handler,        /* header handler */
    sapi_cli_send_headers,          /* send headers handler */
    sapi_cli_send_header,           /* send header handler */

    NULL,                           /* read POST data */
    sapi_cli_read_cookies,          /* read Cookies */

    sapi_cli_register_variables,    /* register server variables */
    sapi_cli_log_message,           /* Log message */
    NULL,                           /* Get request time */
    NULL,                           /* Child terminate */

    STANDARD_SAPI_MODULE_PROPERTIES
};

其实sapi_module_struct 结构体就是 main/SAPI.h中的_sapi_module_struct,他们是通过STANDARD_SAPI_MODULE_PROPERTIES宏解释出来的

六、_sapi_module_struct结构体

_sapi_module_struct定义如下

struct _sapi_module_struct {  // SAPI模块结构
    char *name; // 应用层名称,比如cli,cgi等
    char *pretty_name; // 应用层更易读的名字,比如cli对应的就是Command Line Interface

    int (*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)(const char *str, size_t str_length); // 这个函数告诉php如何输出数据
    void (*flush)(void *server_context); // 提供给php的刷新缓存的函数指针
    zend_stat_t *(*get_stat)(void); // 用来判断要执行文件的权限,来判断是否有执行权限
    char *(*getenv)(char *name, size_t name_len); // 获取环境变量的方法

    void (*sapi_error)(int type, const char *error_msg, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); // 错误处理方法

    int (*header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers); // 这个函数会在我们调用header()的时候被调用
    int (*send_headers)(sapi_headers_struct *sapi_headers); // 发送所有的header
    void (*send_header)(sapi_header_struct *sapi_header, void *server_context); // 单独发送某一个header

    size_t (*read_post)(char *buffer, size_t count_bytes); // 如何获取HTTP POST中的数据
    char *(*read_cookies)(void);  // 如何获取cookie中的数据

    void (*register_server_variables)(zval *track_vars_array); // 这个函数可以给$_SERVER中获取变量
    void (*log_message)(char *message, int syslog_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)(int arg, char *str, zval *destArray); // 对数据进行处理,比如进行安全过滤等。 default_post_reader/tread_data/input_filter是三个能对输入进行过滤和处理的函数
    char *executable_location; // 执行的地理位置

    int php_ini_ignore; // 是否不使用任何ini配置文件,比如php -n 就将这个位置设置为1
    int php_ini_ignore_cwd; // 不在当前路径寻找php.ini

    int (*get_fd)(int *fd); // 获取执行文件的fd

    int (*force_http_10)(void); // 强制使用http1.0

    int (*get_target_uid)(uid_t *); // 获取执行程序的uid
    int (*get_target_gid)(gid_t *); // 获取执行程序的gid

    unsigned int (*input_filter)(int arg, char *var, char **val, size_t val_len, size_t *new_val_len); // 对输入进行过滤。比如将输入参数填充到自动全局变量$_GET, $_POST, $_COOKIE中

    void (*ini_defaults)(HashTable *configuration_hash); // 默认的ini配置
    int phpinfo_as_text; // 是否打印phpinfo信息

    char *ini_entries; // 有没有附带的ini配置,比如使用php -d date.timezone=America/Adak,可以在命令行中设置时区
    const zend_function_entry *additional_functions; // 每个SAPI模块特有的一些函数注册,比如cli的cli_get_process_title
    unsigned int (*input_filter_init)(void); // TODO:
};

相关文章

  • php内核分析(1)sapi_module_struct

    一、环境 centos7.2php版本 7.0如下 二、php模式 PHP具有apache、php-fpm、cl...

  • PHP简单入门

    1.PHP内核Zend PHP由内核Zend引擎和扩展层组成,PHP内核负责处理请求、完成文件流错误处理等操作,Z...

  • jupyter

    运行 安装php内核 下载php-zmq扩展[https://pecl.php.net/package/zmq/1...

  • 好网站

    PHP内核探索深入理解PHP内核RabbitMQ从入门到精通

  • php内核分析---内存管理(一)

    内存是计算机非常关键的部件之一,是暂时存储程序以及数据的空间,CPU只有有限的寄存器可以用于 存储计算数据,而大部...

  • php内核源码分析--哈希表

    按图索骥。PHP中使用最为频繁的数据类型非字符串和数组莫属,PHP比较容易上手也得益于非常灵活的数组类型。 在开始...

  • php内核分析:变量分离/引用

    一、回顾变量结构 在了解php内核是如何进行变量分离和引用的时候,我们要提前了解变量的结构体,如下zval是_zv...

  • php内核

    深入php内核:https://www.kancloud.cn/kancloud/php-internals/42822

  • php内核

    https://github.com/walu/phpbook

  • linux内核分析(1)

    冯磊 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/US...

网友评论

      本文标题:php内核分析(1)sapi_module_struct

      本文链接:https://www.haomeiwen.com/subject/hhqrdqtx.html