为什么我用 C23 而不是 C++ 重写 PHP 扩展
来源:dev.to — 2026-08-09
📋 概述
作者 fork 了 DataStax Cassandra 驱动(它在 PHP 8 上无法编译、维护者大多已离开)。他第一反应是用 C++ 重写新部分:写了 Zend 包装类、全程 RAII、用智能指针包裹 zval——整套现代方案,结果引入了花了好几天才追查到的内存 bug,却没得到有意义的回报。于是驱动改用 C23 重写。作者强调这不是说 C++ 是坏语言:在你能掌控分配器、错误模型和对象生命周期的应用里,std::vector 和 std::unique_ptr 物有所值。但 PHP 扩展不同——Zend 引擎拥有这些规则,而它的规则是用 C 写的。每个抽象都得被"教会" PHP 的生命周期规则,这段教学代码往往比它想简化的活儿还复杂。文章列出四个让他付出真实调试时间的痛点:PHP 拥有分配器(emalloc/efree 体系)、请求级内存模型等。
🔑 核心要点
- 关键矛盾:PHP 扩展里Zend 引擎拥有生命周期规则,而这些规则是用 C 写的
- 不是 C++ 不能调 Zend API,而是阻抗失配:每个抽象都要被教 PHP 的生命周期规则
- PHP 拥有自己的内存管理器(emalloc/efree),普通 new/delete 游离在请求级内存模型之外
- std::vector 默认走 C++ 分配器,需自定义 PhpAllocator 接入 Zend 内存体系
- 作者用 C++ 写出了花几天才找到的内存 bug,却没有任何回报,故改用 C23
💡 金句
在能掌控分配器、错误模型和对象生命周期的应用里,std::vector 和 std::unique_ptr 物有所值;但 PHP 扩展不是这种应用——Zend 引擎拥有那些规则,而它的规则是用 C 写的。
👍 0
👎 0
← 返回 dev.to 首页