This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
PHPX is a C++17 wrapper library for the Zend Engine API, enabling development of PHP extensions in modern C++ with RAII, type-safe wrappers, and an object-oriented API. Requires PHP 8.2+.
# Standard build
cmake . && make -j$(nproc)
sudo make install && sudo ldconfig
# Debug build (symbols, no optimization, runtime checks)
cmake -DCMAKE_BUILD_TYPE=Debug . && make -j$(nproc)
# Coverage build
cmake -DCODE_COVERAGE=ON . && make -j$(nproc)
# ASAN build
cmake -Denable_asan=ON . && make -j$(nproc)Build outputs go to lib/ (libphpx.so, ext.so) and bin/ (phpx-tests).
# C++ tests (Google Test via PHP embed)
./bin/phpx-tests # all tests
./bin/phpx-tests --gtest_filter="variant.*" # filter
./bin/phpx-tests --gtest_list_tests # list
# PHP tests (PHPUnit — requires ext.so loaded)
composer test
# In CI, ext.so is copied to PHP extension dir first:
sudo cp lib/ext.so $(php-config --extension-dir)/phpx_test.soTest infrastructure uses PHP Embed SAPI — tests/src/main.cpp bootstraps php_embed_init, runs GTest inside a PHP eval, then shuts down. The try_call helper asserts exception messages match expected strings.
./format.sh # clang-format -i on src/core/*.cc include/*.h tests/src/*.cppBased on Google style, 120 cols, 4-space indent (see .clang-format).
PHP Extension ── PHPX facade layer (func/class/const) ── Core type wrappers ── Zend Engine API
All live in namespace php. The primary wrapper types:
Variant— universal zval wrapper, the central type. Supports construction from all PHP scalar types, type checking (isString(),isInt(), …), conversion (toString(),toInt(), …), and operator overloading. Uses RAII withzval_ptr_dtoron destruction.Array—zend_arraywrapper.set(key, val),get(key),exists(),append(),count(),foreach(lambda),operator[]. Initializer-list construction:Array{1, 2, 3}orArray{{"k1", v1}, {"k2", v2}}.Object— wrapszend_object.newObject("ClassName", args),call("method", args),getProperty()/setProperty(),callStatic().String—zend_stringwrapper.length(),toStdString(),toCString().Reference— needed when passing arrays to PHP functions that modify them (e.g.,php::sort(arr.toReference())).Box— Stores a C++ pointer as a PHP resource, enabling with-construct/destruct lifecycle.Closure— wraps a C++ lambda into a PHP callable.
Critical rule: PHP headers must always be wrapped in extern "C" {}. See include/phpx.h:23.
PHPX_EXTENSION() {
Extension *ext = new Extension("name", "1.0.0");
ext->onStart = [ext]() noexcept {
// Register classes, functions, constants
};
return ext;
}Macros: PHPX_FUNCTION(name) for functions, PHPX_METHOD(Class, method) for methods. PHPX_FN(fn) / PHPX_ME(Class, method) for registration.
Auto-generated wrappers around PHP built-in functions, classes, and constants. Callable via php::function_name(...) (e.g., php::array_push(), php::strlen()). Facade classes like php::Redis wrap PHP extension classes.
~192KB generated file that pre-registers common string literals with the Zend Engine to avoid repeated allocation.
Generates arginfo headers for extensions — run from extension project directories using php vendor/swoole/phpx/bin/gen_stub.php <stub_dir>.
GitHub Actions (.github/workflows/test.yml): tests against PHP 8.2–8.5 on Ubuntu. Builds with coverage, runs phpx-tests (GTest) then composer test (PHPUnit), uploads coverage to Codecov.