今日已更新 34 条资讯 | 累计 29487 条内容
关于我们

# Why I’m Rewriting a PHP Extension in C23, Not C++

Dusan Malusev 2026年08月08日 23:28 1 次阅读 来源:Dev.to

I forked the DataStax Cassandra driver when it stopped compiling on PHP 8 and most of its maintainers had already moved on. My first instinct was to write the new parts in C++. I built a Zend wrapper class, used RAII throughout, and put smart pointers around zval s—the whole modern setup. It introduced memory bugs that took me days to track down, and I did not get a meaningful benefit in return. So the driver is being rewritten in C23. I want to explain why, because “just use C++; it’s safer” is the reflexive answer. For a PHP extension, I no longer think it is the right one. This is not an argument that C++ is a bad language. In an application where I own the allocator, error model, and object lifetimes, std::vector and std::unique_ptr earn their keep. A PHP extension is different: the Zend Engine owns those rules, and its rules are written in C. The problem is not that C++ cannot call the Zend API. Plenty of extensions do. The problem is impedance: each abstraction has to be taught PHP’s lifetime rules, and the teaching code can become more complicated than the work it was meant to simplify. These are the four places where that cost me real debugging time. PHP owns the allocator PHP has its own memory manager. Request-scoped memory is allocated with functions such as emalloc , ecalloc , and safe_emalloc , then released with efree . Zend tracks that memory and normally reclaims what remains at request shutdown. Persistent allocations use a separate API because they have a different lifetime. Plain malloc and free —and therefore ordinary new and delete —sit outside that request-memory model. The moment I put a std::vector<zval> in an extension, its backing storage uses the C++ allocator unless I replace it. The obvious fix is a custom allocator: template < class T > struct PhpAllocator { using value_type = T ; template < class U > PhpAllocator ( const PhpAllocator < U >& ) noexcept {} PhpAllocator () noexcept = default ; [[ nodiscard ]] T * allocate ( std :: size_t

本文内容来源于互联网,版权归原作者所有
查看原文