【四】说说include特性

前言

说到PHP的include/require特性,有很多大神都解释了,include,require,include_once,require_one归根到底是一种方式,只是异常处理不一样而已。
https://www.kancloud.cn/nickbai/php7/363301这里讲的是PHP7下的,和PHP5下唯一不同是没有AST这一层

image.png

上图也说明了。

在SKL下的include

其实include语法和PHP实现的流程是一模一样的,没有根本区别。
核心代码

void execute_include_statment(include_statement_t *is, statement_list_t *statement_list) {
    char *filename = is->filename;
    FILE *input = fopen(filename, FILE_OPT_READ);
    if (is_empty(input)) {
        error_exception("File:%s can not be read!", filename);
    }
    global_info.include_mode = 1;
    yyrestart(input);
    if (yyparse()) {
        error_exception("System parse file:%s failed !", filename);
    }
    global_info.include_mode = 0;
    // 脚本hash
    if (!find_hash(global_info.script_table, filename, strlen(filename))) {
        insert_or_update_hash(global_info.script_table, filename, strlen(filename), filename);
    }
    merge_execute_statement_list(statement_list);
    fclose(input);
}
/**
 * 执行语句列表合并
 */
void merge_execute_statement_list(statement_list_t *statement_list) {
    if (global_info.include_statement_list->tail) {
        global_info.include_statement_list->tail->next = statement_list->top->next;
        statement_list->top = global_info.include_statement_list->top;
    } else {
        statement_list->top = statement_list->top->next;
    }
    //reset
    global_info.include_statement_list->top = global_info.include_statement_list->tail = NULL;
}

主要流程
1.读取文件流
2.设置全局包含模式为1 (解析后的语句列表放在全局包含语句变量)
3.yyrestart(input)重新解析文件流
4.重置全局包含模式为0
5.将文件地址放入hash表
6.合并全局语句列表和包含语句列表
7.关闭文件流

过程不复杂,但是在查看关于yyrestart的api文档费了点劲,还有执行语句的时候。

结束语

不会时,觉着很高深,完全了解后,也不是很难嘛,还是要有一股霸气

你可能感兴趣的:(【四】说说include特性)