首页 后端开发 php教程 [转]PHP的执行流程,PHP扩展加载过程

[转]PHP的执行流程,PHP扩展加载过程

Jun 23, 2016 pm 01:07 PM

为了以后能开发PHP扩展..就一定要了解PHP的执行顺序..这篇文章就是为C开发PHP扩展做铺垫.
web环境 我们假设为 apache.
在编译PHP的时候,为了能够让Apache支持PHP,我们会生成一个mod_php5.so的模块.apache加载这个模块..
在url访问.php文件的时候就会转给mod_php5.so模块来处理.这个玩意是什么..就是我们常说的SAPI
英文名字是:Server abstraction API.
SAPI说的其实是一个统称,其下有 ISAPI,CLI SAPI, CGI等.
有了它,就可以很容易的跟其他东西交互.比如APACHE,IIS,CGI等.
好了回到正题.
apache启动后会将mod_pho5.so模块的hook handler注册进来.apache今天不是主角,所以不细说.
当APACHE检测到 访问的url是一个php文件时,这时候就会把控制权交给sapi.

如下图:

进入到sapi后,首先会执行sapi/apache/mod_php5.c 文件的php_init_handler函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

static void php_init_handler(server_rec *s, pool *p)

{

         register_cleanup(p, NULL, ( void (*)( void *))apache_php_module_shutdown_wrapper, ( void (*)( void *))php_module_shutdown_for_exec);

         if (!apache_php_initialized) {

                 apache_php_initialized = 1;

#ifdef ZTS

                 tsrm_startup(1, 1, 0, NULL);

#endif

                 sapi_startup(&apache_sapi_module);

                 php_apache_startup(&apache_sapi_module);

         }

#if MODULE_MAGIC_NUMBER >= 19980527

         {

                 TSRMLS_FETCH();

                 if (PG(expose_php)) {

                         ap_add_version_component( "PHP/" PHP_VERSION);

                 }

         }

#endif

}

该函数主要调用 两个函数
sapi_startup(&apache_sapi_module);
php_apache_startup(&apache_sapi_module);

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

SAPI_API void sapi_startup(sapi_module_struct *sf)

{

         sf->ini_entries = NULL;

         sapi_module = *sf;

 

.................

         sapi_globals_ctor(&sapi_globals);

................

 

         virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */

 

..................

 

         reentrancy_startup();

}

sapi_startup创建一个 sapi_globals_struct结构体.
sapi_globals_struct保存了apache请求的基本信息,如服务器信息,header,编码等.

1

2

3

4

5

6

static void sapi_globals_ctor(sapi_globals_struct *sapi_globals TSRMLS_DC)

{

         memset (sapi_globals, 0, sizeof (*sapi_globals));

         zend_hash_init_ex(&sapi_globals->known_post_content_types, 5, NULL, NULL, 1, 0);

         php_setup_sapi_content_types(TSRMLS_C);

}

known_post_content_types是一个HashTable,将其大小初始化为5.从字面意义上我猜测它保存的应该是客户端传递过来的内容类型.
php_setup_sapi_content_types函数将sapi_post_entry添加到sapi_globals里
sapi_startup执行完毕后再执行php_apache_startup

1

2

3

4

5

6

7

8

static int php_apache_startup(sapi_module_struct *sapi_module)

{

         if (php_module_startup(sapi_module, &apache_module_entry, 1) == FAILURE) {

                 return FAILURE;

         } else {

                 return SUCCESS;

         }

}

php_module_startup 内容太多..是介绍一下作用.
1. 初始化zend_utility_functions 结构.这个结构是设置zend的函数指针,比如错误处理函数,输出函数,流操作函数等.
2. 设置环境变量.
3. 加载php.ini配置.
4. 加载php内置扩展.
5. 写日志.
6. 注册php内部函数集.
7. 调用 php_ini_register_extensions,加载所有外部扩展
8. 开启所有扩展
9. 一些清理操作.
重点说一下 3,4,7,8
加载php.ini配置
if (php_init_config(TSRMLS_C) == FAILURE) {
return FAILURE;
}
php_init_config函数会在这里检查所有php.ini配置,并且找到所有加载的模块,添加到php_extension_lists结构中.
加载php内置扩展
调用 zend_register_standard_ini_entries加载所有php的内置扩展,如array,mysql等.
调用 php_ini_register_extensions,加载所有外部扩展
main/php_ini.c

1

2

3

4

5

6

7

8

void php_ini_register_extensions(TSRMLS_D)

{

         zend_llist_apply(&extension_lists.engine, php_load_zend_extension_cb TSRMLS_CC);

         zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb TSRMLS_CC);

 

         zend_llist_destroy(&extension_lists.engine);

         zend_llist_destroy(&extension_lists.functions);

}

zend_llist_apply函数遍历extension_lists 执行会掉函数 php_load_php_extension_cb
php_load_php_extension_cb

1

2

3

4

static void php_load_zend_extension_cb( void *arg TSRMLS_DC)

{

         zend_load_extension(*(( char **) arg));

}

调用 ext/standard/dl.c zend_load_extension 加载扩展,
该函数略过..
该函数最后调用
if ((module_entry = zend_register_module_ex(module_entry TSRMLS_CC)) == NULL) {
DL_UNLOAD(handle);
return FAILURE;
}
将 扩展信息 放到 Hash表module_registry中
Zend/zend_API.c

1

2

3

4

5

if (zend_hash_add(&module_registry, lcname, name_len+1, ( void *)module, sizeof (zend_module_entry), ( void **)&module_ptr)==FAILURE) {

                 zend_error(E_CORE_WARNING, "Module '%s' already loaded" , module->name);

                 efree(lcname);

                 return NULL;

}

最后
zend_startup_modules(TSRMLS_C); //对模块进行排序,并检测是否注册到module_registry HASH表里

zend_startup_extensions(); //执行extension->startup(extension);启动扩展…

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

PHP记录:PHP日志分析的最佳实践 PHP记录:PHP日志分析的最佳实践 Mar 10, 2025 pm 02:32 PM

PHP日志记录对于监视和调试Web应用程序以及捕获关键事件,错误和运行时行为至关重要。它为系统性能提供了宝贵的见解,有助于识别问题并支持更快的故障排除

在Laravel中使用Flash会话数据 在Laravel中使用Flash会话数据 Mar 12, 2025 pm 05:08 PM

Laravel使用其直观的闪存方法简化了处理临时会话数据。这非常适合在您的应用程序中显示简短的消息,警报或通知。 默认情况下,数据仅针对后续请求: $请求 -

php中的卷曲:如何在REST API中使用PHP卷曲扩展 php中的卷曲:如何在REST API中使用PHP卷曲扩展 Mar 14, 2025 am 11:42 AM

PHP客户端URL(curl)扩展是开发人员的强大工具,可以与远程服务器和REST API无缝交互。通过利用Libcurl(备受尊敬的多协议文件传输库),PHP curl促进了有效的执行

简化的HTTP响应在Laravel测试中模拟了 简化的HTTP响应在Laravel测试中模拟了 Mar 12, 2025 pm 05:09 PM

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显着减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

在Codecanyon上的12个最佳PHP聊天脚本 在Codecanyon上的12个最佳PHP聊天脚本 Mar 13, 2025 pm 12:08 PM

您是否想为客户最紧迫的问题提供实时的即时解决方案? 实时聊天使您可以与客户进行实时对话,并立即解决他们的问题。它允许您为您的自定义提供更快的服务

解释PHP中晚期静态结合的概念。 解释PHP中晚期静态结合的概念。 Mar 21, 2025 pm 01:33 PM

文章讨论了PHP 5.3中引入的PHP中的晚期静态结合(LSB),从而允许静态方法的运行时分辨率调用以获得更灵活的继承。 LSB的实用应用和潜在的触摸

自定义/扩展框架:如何添加自定义功能。 自定义/扩展框架:如何添加自定义功能。 Mar 28, 2025 pm 05:12 PM

本文讨论了将自定义功能添加到框架上,专注于理解体系结构,识别扩展点以及集成和调试的最佳实践。

See all articles