Mengikuti artikel sebelumnya mari kita bincangkan tentang kitaran hayat php dan lihat cangkuk mana yang dilanjutkan untuk melakukan apa , php Kitaran hayat mempunyai kira-kira 5 peringkat, peringkat permulaan modul php_module_startup
, peringkat permulaan permintaan php_request_startup
, peringkat pelaksanaan skrip php_execute_script
, peringkat penutup permintaan php_request_shutdown
, peringkat penutup modul php_module_shutdown
, yang diperkenalkan di bawah dalam mod cli.
php_module_startup
Mari kita lihat apa yang dilakukan dalam peringkat ini Jika anda tidak tahu di mana fail masukan php itu, gunakan gdb untuk melihat timbunan panggilan, gdb ./php
Pada php_module_startup
titik putus, laksanakan, lihat timbunan panggilan,
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
Anda boleh melihat dengan jelas proses pelaksanaan dalam timbunan panggilan, sekarang pergi ke fail /main/main.c untuk melihat perkara yang perlu dilakukan Anda juga boleh menggunakan gdb untuk melihat langkah demi langkah perkara yang telah dilakukan Berikut adalah beberapa tempat yang berkaitan dengan pelanjutan PHP yang dilakukan di sini, seperti sampah pengumpulan, pemulaan permintaan, pemalar pendaftaran, pemuatan fail konfigurasi php.ini, dsb.
Mari kita lihat dahulu cara memuatkan modul
/* startup extensions statically compiled in */ if (php_register_internal_extensions_func() == FAILURE) { php_printf("Unable to start builtin modules\n"); return FAILURE; }
Berikut memuatkan modul terbina dalam php. Hanya fungsi teras disiarkan di sini dahulu
/* 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; }
Ini adalah prinsip memuatkan modul terbina dalam. Sekarang mari lihat bagaimana sambungan dalam ini dimuatkan
php_ini_register_extensions();
zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb);
Gunakan fungsi ini untuk memuatkan
php_load_extension(char *filename, int type, int start_now)
Memuatkan terbina dalam turut dilaksanakan di sini kefungsian modul.
memanggil module->functions
untuk mendaftarkan fungsi fungsi modul Sekarang kita tahu mengapa fungsi fungsi itu harus ditulis di sini 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 };
Sekarang mari kita lihat beberapa cangkuk. Fungsi sambungan
/* start Zend extensions */ zend_startup_extensions();
Inti di sini ialah func(element->data)
iaitu pengembangan pelaksanaan
PHP_MINIT
Fungsi
element=l->head; while (element) { next = element->next; if (func(element->data)) { DEL_LLIST_ELEMENT(element, l); } element = next; }
Sekarang anda tahu bahawa PHP_MINIT
cangkuk boleh melakukan banyak fungsi Permulaan, cara mendaftar kelas fungsi lanjutan tersuai, cara menulis pembolehubah lanjutan ke dalam php.ini, cara menulis semula fungsi terbina dalam 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);
Berikut ialah penulisan semula var_dump fungsi, pendaftaran Saya telah mencipta kelas orang, yang akan saya perkenalkan di sini dahulu Bahagian seterusnya akan memperkenalkan cara menjana AST melalui analisis leksikal dan analisis sintaks kod PHP, dan kemudian menyusun arahan opcode untuk memanggil. oleh mesin maya zend.
Pembelajaran yang disyorkan: "Tutorial Video PHP"