本文目录导读:

我来详细解释PHP内核的启动过程,这是一个复杂的多阶段过程,我将其分为主要阶段来说明。
模块初始化阶段 (Module Init)
// PHP源码 sapi/cli/php_cli.c
int main(int argc, char *argv[])
{
// 1. 初始化PHP全局变量
php_module_startup();
// 2. 初始化SAPI(服务器API)
sapi_startup(&cli_sapi_module);
// 3. 注册内置函数和类
zend_startup();
// 4. 加载配置文件(php.ini)
php_init_config();
}
Zend引擎初始化
// Zend引擎核心初始化
void zend_startup(void)
{
// 1. 初始化内存管理器
zend_mm_startup();
// 2. 初始化符号表
zend_hash_init();
// 3. 初始化函数表
zend_function_startup();
// 4. 注册核心函数
zend_register_functions();
// 5. 初始化类表
zend_class_startup();
}
内存管理器初始化
// Zend内存管理器(Zend MM)
typedef struct _zend_mm_heap {
// 内存池
void *storage;
// 小内存缓存
zend_mm_free_block *free_buckets[ZEND_MM_NUMBER_BUCKETS];
// 大内存块
zend_mm_chunk *chunks;
} zend_mm_heap;
void zend_mm_startup()
{
// 创建内存堆
AG(mm_heap) = zend_mm_create_heap();
// 初始化缓存
zend_mm_init_cache();
}
扩展加载过程
// 加载PHP扩展
void php_load_extensions(void)
{
// 1. 加载静态编译的扩展
for (zend_extension_entry = php_extensions;
zend_extension_entry->name;
zend_extension_entry++) {
zend_load_extension(zend_extension_entry);
}
// 2. 加载动态扩展(.so文件)
if (cfg_get_entry("extension", &extension_name)) {
dl_load(extension_name);
}
}
SAPI初始化
// SAPI(服务器API)初始化
static int sapi_cli_startup(sapi_module_struct *sapi_module)
{
// 1. 设置SAPI回调函数
sapi_module->activate = php_cli_activate;
sapi_module->deactivate = php_cli_deactivate;
// 2. 初始化请求数据结构
SG(server_context) = NULL;
// 3. 设置输出处理
sapi_module->sapi_error = php_error;
// 4. 初始化全局变量
SG(headers_sent) = 0;
SG(request_info) = {0};
}
请求处理循环
// 伪代码展示处理流程
while (有请求) {
// 1. 请求开始
php_request_startup();
// 2. 编译脚本
zend_file_handle handle;
zend_execute_script(handle);
// 3. 执行代码
zend_execute(op_array);
// 4. 请求结束
php_request_shutdown();
// 5. 资源清理
zend_objects_store_free();
}
实际启动时序
时间线:
[0ms] 开始启动
[1ms] SAPI初始化
[5ms] 内存管理器初始化
[10ms] 核心扩展加载
[15ms] 配置文件解析
[20ms] 所有扩展加载完成
[25ms] 模块初始化完成
[30ms] 准备接收请求
关键数据结构
// 重要的全局数据结构
struct _php_core_globals {
zend_bool magic_quotes_gpc;
zend_bool register_globals;
// ...
};
// Zend引擎全局变量
struct _zend_executor_globals {
HashTable symbol_table;
HashTable function_table;
HashTable class_table;
// ...
};
// 内存管理结构
typedef struct _zend_mm_heap {
size_t size;
zend_mm_free_block *free_buckets[32];
// ...
};
启动流程图
PHP启动流程:
┌─────────────────┐
│ main() 入口 │
└────────┬────────┘
▼
┌─────────────────┐
│ php_module_init()│
└────────┬────────┘
▼
┌─────────────────┐
│ sapi_startup() │
└────────┬────────┘
▼
┌─────────────────┐
│ zend_startup() │
└────────┬────────┘
▼
┌─────────────────┐
│ 加载扩展 │
└────────┬────────┘
▼
┌─────────────────┐
│ 解析php.ini │
└────────┬────────┘
▼
┌─────────────────┐
│ 等待请求 │
└─────────────────┘
性能优化点
// 启动时的优化选项 // 1. 预编译(OPcache) php_opcache_startup(); // 2. 共享内存 zend_shared_memory_init(); // 3. 惰性加载(延迟加载) zend_lazy_function_init();
这个启动过程确保了PHP能够:
- 正确初始化内存管理
- 加载必要扩展和配置
- 准备好接收和处理请求
- 提供高效的内存和资源管理
启动完成后,PHP就进入了请求处理循环,等待接收并处理客户端请求。