必须精准匹配GCC与PHP 7.1 ABI规范,确保gcc/g++≥4.8且禁用CXX11 ABI;使用同源phpize/php-config;config.m4中添加PHP_REQUIRE_CXX;Makefile中追加-lstdc++ -lcrypt;启用-fvisibility=hidden;php.ini中用extension=myext.so加载。

要在PHP 7.1环境中成功开发并编译一个C语言扩展,必须精准匹配GCC编译器行为与PHP 7.1内核的ABI规范,否则会出现undefined symbol、zend_object_handle未定义、或configure阶段直接报错“C++ preprocessor fails sanity check”等致命问题。
确认GCC版本与基础编译链可用性
执行 gcc --version 和 g++ --version,确保二者版本一致且 ≥4.8;PHP 7.1不兼容GCC 10+的默认新ABI(_GLIBCXX_USE_CXX11_ABI=1),若版本过高,必须显式降级或加编译标志。
运行 phpize -v,输出应为 PHP 7.1.x —— 若提示 command not found,说明未安装 php-devel 包,需先执行 yum install php71w-devel(CentOS)或 apt-get install php7.1-dev(Ubuntu)。
【关键前提】 必须使用与当前运行中PHP二进制文件**完全同源编译的phpize和php-config**;混用不同源(如系统包管理器装的phpize + 自编译PHP)会导致zval结构体偏移错乱,make时大量字段报错。
生成扩展骨架并修正config.m4
进入PHP源码目录下的 ext/ 子目录,执行:./ext_skel --extname=myext。
打开生成的 config.m4,找到类似 PHP_ARG_ENABLE(myext, whether to enable myext support, 的行,在其下方添加两行:
if test "$PHP_MYEXT" != "no"; then PHP_REQUIRE_CXX PHP_NEW_EXTENSION(myext, myext.c, $ext_shared)fi
这一步强制启用C++链接支持——PHP 7.1的Zend引擎内部大量使用C++风格符号(如std::string隐式调用),不加 PHP_REQUIRE_CXX 会导致最终so加载时 missing symbol _ZStlsI... 类错误。
配置与编译:GCC核心选项设置
在扩展根目录下依次执行:
第一步:phpize
第二步:./configure --enable-myext --with-php-config=/usr/local/php/bin/php-config(路径按实际调整)
第三步:手动编辑生成的 Makefile,定位到 EXTRA_LIBS = 行末尾,在已有库列表后追加 -lstdc++ -lcrypt;PHP 7.1的configure脚本不会自动补全C++标准库依赖,漏掉会导致 undefined reference to `__cxa_pure_virtual'。
第四步:make —— 此时GCC实际调用命令已含关键参数:-std=gnu99 -fvisibility=hidden -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1。其中 -fvisibility=hidden 是PHP 7.1扩展安全强制项,不启用会导致符号冲突引发段错误。
验证与加载扩展
执行 make install 后,检查输出的.so文件路径(通常为 /usr/lib64/php/modules/myext.so 或 /usr/local/php/lib/php/extensions/no-debug-zts-xxxxx/myext.so)。
编辑 php.ini,在末尾添加:extension=myext.so;注意不要写成 extension=/full/path/to/myext.so —— PHP 7.1不支持绝对路径加载扩展,会静默忽略。
运行 php -m | grep myext,有输出即表示加载成功;若报错 undefined symbol: zend_register_internal_class_ex,说明 configure 阶段未正确识别PHP头文件路径,需检查 --with-php-config 指向是否包含 include/php 目录。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











