成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

PHP-7.1 源代碼學(xué)習(xí):php-cli 啟動(dòng)流程

VishKozus / 3107人閱讀

摘要:前言函數(shù)默認(rèn)構(gòu)建目標(biāo)為,相關(guān)代碼在目錄下,文件中能夠找到入口函數(shù),大概流程如下命令行參數(shù)處理初始化清理工作語(yǔ)言系統(tǒng)編程常用手法,通過(guò)中聲明函數(shù)指針類型的字段來(lái)實(shí)現(xiàn)類似面向?qū)ο笾谐橄箢惖母拍?,在文件中可以找到該結(jié)構(gòu)體的定義,這里只列出部分

前言 php cli main 函數(shù)

configure & make 默認(rèn)構(gòu)建目標(biāo)為 php-cli,相關(guān)代碼在 sapi/cli 目錄下,php_cli.c 文件中能夠找到 main(入口)函數(shù),大概流程如下:

命令行參數(shù)處理

cli_sapi_module 初始化

sapi_module->startup

do_cli or do_cli_server

清理工作

sapi_module_struct

C 語(yǔ)言系統(tǒng)編程常用手法,通過(guò) struct 中聲明 函數(shù)指針 類型的字段來(lái)實(shí)現(xiàn)類似面向?qū)ο笾谐橄箢惖母拍?,?main/SAPI.h 文件中可以找到該結(jié)構(gòu)體的定義,這里只列出部分字段(下同):

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);
    ...
    char *ini_entries;
    const zend_function_entry *additional_functions;
    unsigned int (*input_filter_init)(void);
}
cli_sapi_module

cli_sapi_module 是一個(gè)靜態(tài)全局變量,定義在 php_cli.c 中,你可以將它理解成是 sapi_module_struct "類" 的一個(gè) "實(shí)例",結(jié)構(gòu)體中 "掛載" 了 cli 特定的實(shí)現(xiàn)函數(shù):

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

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

    STANDARD_SAPI_MODULE_PROPERTIES
};
do_cli

do_cli 函數(shù)定義在 php_cli.c 文件中,大致流程如下:

根據(jù)命令行選項(xiàng) 確定 behavior(解釋器行為)

根據(jù) behavior 執(zhí)行相應(yīng)的動(dòng)作

通過(guò)執(zhí)行 sapi/cli/php --help 可以查看所有的 php-cli 命令行選項(xiàng),我們通過(guò)幾個(gè)簡(jiǎn)單的選項(xiàng)來(lái)分析解釋器執(zhí)行流程

PHP_MODE_CLI_DIRECT

該模式下,php-cli 會(huì)執(zhí)行解釋執(zhí)行通過(guò)命令行參數(shù)傳遞的 code

case PHP_MODE_CLI_DIRECT:
    cli_register_file_handles();
    if (zend_eval_string_ex(exec_direct, NULL,   
        "Command line code", 1) == FAILURE) {
                exit_status=254;
    }
    break;

追蹤 zend_eval_string_ex 的函數(shù)調(diào)用,定位到 zend_execute_API.c 文件中 zend_eval_stringl 函數(shù),代碼邏輯已經(jīng)很清楚了:先調(diào)用 zend_compile_string 函數(shù)編譯代碼生成字節(jié)碼 new_op_array,再調(diào)用 zend_execute 函數(shù)執(zhí)行生成的字節(jié)碼

ZEND_API int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr,   
char *string_name) {
    ...
    original_compiler_options = CG(compiler_options);
    CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
    new_op_array = zend_compile_string(&pv, string_name);
    CG(compiler_options) = original_compiler_options;

    if (new_op_array) {
        zend_try {
            ZVAL_UNDEF(&local_retval);
            zend_execute(new_op_array, &local_retval);
        } zend_catch {
            destroy_op_array(new_op_array);
            efree_size(new_op_array, sizeof(zend_op_array));
            zend_bailout();
        } zend_end_try();
        ...
    } else {
        retval = FAILURE;
    }
    zval_dtor(&pv);
    return retval;
}

zend_compile_string 屬于語(yǔ)法分析內(nèi)容,參考 PHP-7.1 源代碼學(xué)習(xí): 語(yǔ)法分析,這里做個(gè)簡(jiǎn)要介紹

compile_string

通過(guò)搜索源代碼可以發(fā)現(xiàn) zend_compile_string 最終調(diào)用 compile_string

zend_op_array *compile_string(zval *source_string, char *filename)
{
    zend_lex_state original_lex_state;
    zend_op_array *op_array = NULL;
    zval tmp;

    if (Z_STRLEN_P(source_string)==0) {
        return NULL;
    }

    ZVAL_DUP(&tmp, source_string);
    convert_to_string(&tmp);
    source_string = &tmp;

    zend_save_lexical_state(&original_lex_state);
    if (zend_prepare_string_for_scanning(source_string, filename) == SUCCESS) {
        BEGIN(ST_IN_SCRIPTING);
        op_array = zend_compile(ZEND_EVAL_CODE);
    }

    zend_restore_lexical_state(&original_lex_state);
    zval_dtor(&tmp);

    return op_array;
}
總結(jié)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/22325.html

相關(guān)文章

  • PHP-7.1 代碼學(xué)習(xí):字節(jié)碼生成 之 "$a = 1"

    摘要:前言本文通過(guò)分析這個(gè)語(yǔ)句的編譯和執(zhí)行來(lái)窺探解釋執(zhí)行邏輯準(zhǔn)備參考之前的系列文章,在環(huán)境下下載,編譯源代碼將代碼導(dǎo)入中編輯運(yùn)行選項(xiàng),增加運(yùn)行參數(shù)設(shè)置斷點(diǎn)開(kāi)始調(diào)試是一個(gè)測(cè)試腳本,放在目錄下,中只包含一條簡(jiǎn)單的賦值語(yǔ)句調(diào)用堆棧參考之前的系列文章 前言 本文通過(guò)分析 $a=1 這個(gè) PHP 語(yǔ)句的編譯和執(zhí)行來(lái)窺探 php-cli 解釋執(zhí)行邏輯 準(zhǔn)備 參考之前的系列文章,在 ubuntu 環(huán)境下...

    ConardLi 評(píng)論0 收藏0
  • Mac使用dinghy和laradock搭建php運(yùn)行環(huán)境

    摘要:配置例如文件的目錄關(guān)系如下打開(kāi)文件,修改的值為項(xiàng)目文件的相對(duì)路徑,這個(gè)路徑會(huì)映射到容器的目錄上,注意任何修改配置文件都需要執(zhí)行容器名字重新構(gòu)建相關(guān)容器。 背景 每次更換一個(gè)工作用的電腦,都需要很長(zhǎng)的時(shí)間來(lái)搭建本地的運(yùn)行環(huán)境。有時(shí)候,為了安裝一個(gè)擴(kuò)展會(huì)折騰半天,而且可能需要安裝多個(gè)版本的 php。有人說(shuō),集成運(yùn)行環(huán)境不是很好嘛,一次搞定所有的要求。是的,對(duì)于新手來(lái)說(shuō),使用集成包就足夠了。...

    ZoomQuiet 評(píng)論0 收藏0
  • PHP-7.1 代碼學(xué)習(xí):字節(jié)碼生成 之 概述

    摘要:前言字節(jié)碼生成編譯的代碼主要集中在,文件中包含大量的函數(shù),基本上一個(gè)函數(shù)對(duì)應(yīng)語(yǔ)法規(guī)則文件一個(gè)非終結(jié)符,函數(shù)是所有函數(shù)的入口數(shù)據(jù)結(jié)構(gòu)結(jié)構(gòu)體是字節(jié)碼抽象結(jié)構(gòu)體并沒(méi)有像名字那樣簡(jiǎn)單,它包含了大量的字段供虛擬機(jī)在運(yùn)行時(shí)使用一如既往的簡(jiǎn)單,直觀,相比 前言 字節(jié)碼生成(編譯)的代碼主要集中在 zend_compile.c ,文件中包含大量的 zend_compile_xxx 函數(shù),基本上一個(gè)函數(shù)...

    1fe1se 評(píng)論0 收藏0
  • 使用Docker統(tǒng)一團(tuán)隊(duì)的開(kāi)發(fā)環(huán)境

    摘要:開(kāi)場(chǎng)白作為一個(gè)技術(shù)團(tuán)隊(duì)的,你是如何保證成員的開(kāi)發(fā)環(huán)境達(dá)到公司的標(biāo)準(zhǔn),或者是你定制的最低要求的如果你的回答是差不多就行了,有問(wèn)題再說(shuō),那么,你已經(jīng)在給自己挖坑了。好的,成員們開(kāi)始構(gòu)建你定制的開(kāi)發(fā)環(huán)境了。 開(kāi)場(chǎng)白 作為一個(gè)技術(shù)團(tuán)隊(duì)的Leader,你是如何保證成員的開(kāi)發(fā)環(huán)境達(dá)到公司的標(biāo)準(zhǔn),或者是你定制的最低要求的?如果你的回答是:差不多就行了,有問(wèn)題再說(shuō),那么,你已經(jīng)在給自己挖坑了。 同事A...

    alin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<