You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP8.2.8线程安全扩展开发遇阻:VS2022编译NTS模块报错

PHP 8.2.8 TS扩展编译后被识别为NTS的问题解决

问题背景

在WAMP环境下用Visual Studio 2022开发PHP扩展,目标适配Windows Server上的Apache 2.4.x + PHP 8.2.8 TS 64位环境。编译链接能正常生成php_helloworld.dll,但启动PHP时始终报错,提示模块为非线程安全(NTS),与PHP的线程安全(TS)版本不匹配。

运行与开发环境

  • 服务器环境:Windows Server + Apache 2.4.x
  • PHP版本:8.2.8 TS 64位(Build ID: API20220829,TS,VS16)
  • 开发工具:Visual Studio 2022 + Windows SDK 10
  • 依赖开发包:php-devel-pack-8.2.8-Win32-vs16-x64

当前项目配置

  • 预处理器定义:ZEND_THREAD_SAFE; ZEND_WIN32; PHP_WIN32
  • 链接库:php8ts.lib
  • 语言标准:ISO C++ 14
  • 运行时库:Multi-threaded DLL (/MD)

错误提示

PHP Warning: PHP Startup: php_helloworld: Unable to initialize module:
Module compiled with build ID=API20220829,NTS,VS16
PHP compiled with build ID=API20220829,TS,VS16

测试代码

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include "php.h"

#define ZEND_DEBUG 0

// Declare the function
PHP_FUNCTION(php_helloworld);

// register our function to the PHP API
// so that PHP knows, which functions are in this module
zend_function_entry php_helloworld_functions[] =
{
    PHP_FE(php_helloworld, NULL),
    {NULL, NULL, NULL}
};

// some pieces of information about our module
zend_module_entry php_helloworld_module_entry =
{
    STANDARD_MODULE_HEADER,
    "php_helloworld", // Extension name
    php_helloworld_functions, // Function entry
    NULL, // Module initialization
    NULL, // Module shutdown
    NULL, // Request initialization (not used)
    NULL, // Request shutdown (not used)
    NULL, // Extension info (not used)
    "1.0", // Extension version
    STANDARD_MODULE_PROPERTIES
};

// use a macro to output additional C code, to make ext dynamically loadable
ZEND_GET_MODULE(php_helloworld)

// Finally, we implement our "Hello World" function
// this function will be made available to PHP
// and prints to PHP stdout using printf
PHP_FUNCTION(php_helloworld)
{
    php_printf("Hello World! (from our extension)\n");
}

解决方案

1. 确认项目平台与预处理器定义

  • 检查VS项目的平台配置,确保是x64,与PHP的64位版本完全匹配。
  • 进入项目属性 -> C/C++ -> 预处理器 -> 预处理器定义,确认ZEND_THREAD_SAFE存在,且没有被ZEND_NOT_THREAD_SAFE覆盖(避免复制粘贴引入多余定义)。

2. 修正模块属性宏

PHP 8.x中,STANDARD_MODULE_PROPERTIES宏需要依赖ZEND_THREAD_SAFE的定义生成TS标识。如果宏未正确生效,可替换为STANDARD_MODULE_PROPERTIES_EX:

zend_module_entry php_helloworld_module_entry =
{
    STANDARD_MODULE_HEADER,
    "php_helloworld",
    php_helloworld_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    "1.0",
    STANDARD_MODULE_PROPERTIES_EX
};

该宏会根据预处理器定义自动注入TS/NTS属性。

3. 验证开发包文件一致性

  • 确认项目引用的PHP头文件(如php.h)全部来自php-devel-pack-8.2.8-Win32-vs16-x64,没有混用NTS版本的头文件。
  • 链接的库文件必须是开发包中的php8ts.lib,绝对不能用NTS版本的php8.lib。

4. 清理缓存后重新编译

  • 删除VS项目的Debug/Release输出目录,清除所有中间编译文件。
  • 重启Visual Studio,重新生成整个解决方案,避免旧缓存导致的配置不生效。

5. 手动检查模块标识

编译完成后,可通过工具(如Dependency Walker)查看php_helloworld.dll的导出表,确认是否包含_zend_get_module导出,且模块信息中带有TS标识。

内容的提问来源于stack exchange,提问作者Simon Fox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 23:48:19