久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網
      最全最豐富的資訊網站

      PHP如何自定義擴展(二)之鉤子功能

      接著上篇來講php生命周期,看看擴展哪些鉤子做哪些事,php生命周期大概5個階段,模塊初始化階段php_module_startup,請求初始化階段php_request_startup,腳本執(zhí)行階段php_execute_script,請求關閉階段php_request_shutdown,模塊關閉階段php_module_shutdown,下面以cli模式介紹。

      php_module_startup

      先看看這個階段做了什么,如果不知道php入口文件在哪,用gdb看看調用棧,gdb ./php

      php_module_startup打斷點,執(zhí)行,在看下調用棧,

      b php_module_startup (gdb) r test.php bt php_module_startup (sf=0x1406460 <cli_sapi_module>,      additional_modules=0x0, num_additional_modules=0)     at /www/test/php/php-7.4.3/main/main.c:2098 #1  0x00000000008bae7c in php_cli_startup (     sapi_module=0x1406460 <cli_sapi_module>)     at /www/test/php/php-7.4.3/sapi/cli/php_cli.c:407 #2  0x00000000008bcc80 in main (argc=2, argv=0x1425af0)     at /www/test/php/php-7.4.3/sapi/cli/php_cli.c:1323

      在調用??梢郧宄吹綀?zhí)行流程,現(xiàn)在到/main/main.c文件看看做了哪些事情,也可以用gdb一步一步的看,這里就講與php擴展有關的幾個地方,這里做的初始化工作,像垃圾回收,請求初始化,注冊常量,php.ini配置文件加載等,

      先來看看怎么加載模塊的

      /* startup extensions statically compiled in */     if (php_register_internal_extensions_func() == FAILURE) {         php_printf("Unable to start builtin modulesn");         return FAILURE;     }

      這里是加載php內置的模塊,這里只貼出核心功能,先檢查依賴

      /* Check module dependencies */     if (module->deps) {         const zend_module_dep *dep = module->deps;          while (dep->name) {             if (dep->type == MODULE_DEP_CONFLICTS) {                 name_len = strlen(dep->name);                 lcname = zend_string_alloc(name_len, 0);                 zend_str_tolower_copy(ZSTR_VAL(lcname), dep->name, name_len);                  if (zend_hash_exists(&module_registry, lcname) || zend_get_extension(dep->name)) {                     zend_string_efree(lcname);                     /* TODO: Check version relationship */                     zend_error(E_CORE_WARNING, "Cannot load module '%s' because conflicting module '%s' is already loaded", module->name, dep->name);                     return NULL;                 }                 zend_string_efree(lcname);             }             ++dep;         }     }
      if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type)==FAILURE) {         zend_hash_del(&module_registry, lcname);         zend_string_release(lcname);         EG(current_module) = NULL;         zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load", module->name);         return NULL;     }

      這是內置模塊加載原理,現(xiàn)在看看ini里的擴展怎么加載

      php_ini_register_extensions();
      zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb);

      利用這個函數加載

      php_load_extension(char *filename, int type, int start_now)

      這里面也執(zhí)行了加載內置模塊的功能。

      是調用了module->functions,進行模塊功能函數注冊,現(xiàn)在知道了為什么功能函數要寫在helloworld_functions這里吧

      zend_module_entry helloworld_module_entry = {     STANDARD_MODULE_HEADER,     "helloworld",                    /* Extension name */     helloworld_functions,            /* zend_function_entry */     PHP_MINIT(helloworld),                            /* PHP_MINIT - Module initialization */     NULL,                            /* PHP_MSHUTDOWN - Module shutdown */     PHP_RINIT(helloworld),            /* PHP_RINIT - Request initialization */     NULL,                            /* PHP_RSHUTDOWN - Request shutdown */     PHP_MINFO(helloworld),            /* PHP_MINFO - Module info */     PHP_HELLOWORLD_VERSION,        /* Version */     PHP_MODULE_GLOBALS(pib),     NULL,     NULL,     NULL,     STANDARD_MODULE_PROPERTIES_EX };

      現(xiàn)在看看擴展的幾個鉤子函數

      /* start Zend extensions */     zend_startup_extensions();

      這里的核心就是func(element->data)也就是執(zhí)行擴展

      PHP_MINIT函數

      element=l->head;     while (element) {         next = element->next;         if (func(element->data)) {             DEL_LLIST_ELEMENT(element, l);         }         element = next;     }

      現(xiàn)在就知道PHP_MINIT鉤子可以做很多初始化的功能,怎么注冊一個自定義擴展的功能類,怎么把擴展的變量寫到php.ini里面,怎么重寫php內置函數,

      original = zend_hash_str_find_ptr(CG(function_table), "var_dump", sizeof("var_dump")-1);      if (original != NULL) {          original->internal_function.handler = my_overwrite_var_dump;     }      zend_class_entry person;     INIT_CLASS_ENTRY(person,CLASS_NAME,person_functions);     zend_register_internal_class_ex(&person,NULL);

      這里就是重寫var_dump函數,注冊了一個person類,先介紹到這里,下篇就介紹怎么把php代碼通過詞法分析語法分析生成AST,然后編譯opcode指令,供zend虛擬機調用。

      推薦學習:《PHP視頻教程》

      贊(0)
      分享到: 更多 (0)
      網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號