PHP内核源码阅读过程(八)

本文详细介绍了PHP的do_cli执行过程,包括打开脚本文件、php_request_startup请求启动、zend_interned_strings_activate字符串表初始化、php_output_activate输出结构初始化、zend_engine激活以及sapi、信号处理和输出控制等相关步骤。每个阶段的关键操作被逐一剖析,为理解PHP内核提供了深入视角。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

php_module_startup执行完成后,接下来就执行do_cli, php的主要执行逻辑都在这里。

	zend_first_try {
			exit_status = do_cli(argc, argv);
	} zend_end_try();

do_cli已经来就是检查参数的2个大循环,这里不讨论这些参数,我们以最简单的启动方式来讲:php xxx.php

 一、打开脚本文件

if (script_file)
{
	if (cli_seek_file_begin(&file_handle, script_file, &lineno) != SUCCESS)
	{
		goto err;
	}
	else
	{
		char real_path[MAXPATHLEN];
		if (VCWD_REALPATH(script_file, real_path))
		{
			translated_path = strdup(real_path);
		}
		script_filename = script_file;
	}
}

二、php_request_startup 启动请求

这个函数内容比较多,接下来就讲这个

三、zend_interned_strings_activate 初始化本次请求的字符串表

ZEND_API void zend_interned_strings_activate(void)
{
	zend_init_interned_strings_ht(&CG(interned_strings), 0);
}

四、php_output_activate 初始化输出结构

PHPAPI int php_output_activate(void)
{
	memset(&output_globals, 0, sizeof(zend_output_globals));

	zend_stack_init(&OG(handlers), sizeof(php_output_handler *));
	OG(flags) |= PHP_OUTPUT_ACTIVATED;

	return SUCCESS;
}

五、zend_activate 激活zend引擎

包括一下操作:

1. gc_reset: 重置gc

2. init_compiler: 初始化编译器

3. init_executor: 初始化执行器

4. startup_scanner: 初始化词法分析和语法分析

以上四个每一个展开都很大,这里暂时不写。

六、sapi_activate 初始化sapi

这里包括四个过程:

1. 初始化 sapi_globals 结构

2. 如果是"post"方式请求,这读取post数据

3. 读取cookies

4. 调用sapi_module的activate函数和input_filter_init函数(假如不为空)

七、zend_signal_activate 注册系统信号的回调

#  define SIGG(v) (zend_signal_globals.v)

void zend_signal_activate(void)
{
	size_t x;

	memcpy(&SIGG(handlers), &global_orig_handlers, sizeof(global_orig_handlers));

	for (x = 0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) {
		zend_signal_register(zend_sigs[x], zend_signal_handler_defer);
	}

	SIGG(active) = 1;
	SIGG(depth)  = 0;
}

八、设置输入的超时时间(从接收所有数据到执行脚本的时间)

		if (PG(max_input_time) == -1) {
			zend_set_timeout(EG(timeout_seconds), 1);
		} else {
			zend_set_timeout(PG(max_input_time), 1);
		}

九、response里增加php版本号的头


#define SAPI_PHP_VERSION_HEADER		"X-Powered-By: PHP/" PHP_VERSION

		if (PG(expose_php)) {
			sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
		}

是否增加这个头,取决于ini的配置,默认是有这个头。

十、输出控制

		if (PG(output_handler) && PG(output_handler)[0]) {
			zval oh;

			ZVAL_STRING(&oh, PG(output_handler));
			php_output_start_user(&oh, 0, PHP_OUTPUT_HANDLER_STDFLAGS);
			zval_ptr_dtor(&oh);
		} else if (PG(output_buffering)) {
			php_output_start_user(NULL, PG(output_buffering) > 1 ? PG(output_buffering) : 0, PHP_OUTPUT_HANDLER_STDFLAGS);
		} else if (PG(implicit_flush)) {
			php_output_set_implicit_flush(1);
		}

有三种互斥的输出控制

1. 重定向到一个内部输出函数

2. 输出控制。在cli模式下,这个无效

3. 输出即时刷新。在cli模式下,这个一直有效

 

累了,明天再写。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值