swoole / phpx
C++ wrapper for Zend API
Requires
- php: >=8.4 <8.6
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.75
- phpunit/phpunit: ^10.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- v2.9.0
- dev-master / 2.8.x-dev
- v2.8.2
- v2.8.1
- v2.8.0
- v2.7.0
- v2.6.13
- v2.6.12
- v2.6.11
- v2.6.10
- v2.6.9
- v2.6.8
- v2.6.7
- v2.6.6
- v2.6.5
- v2.6.4
- v2.6.3
- v2.6.2
- v2.6.1
- v2.6.0
- v2.5.6
- v2.5.5
- v2.5.4
- v2.5.3
- v2.5.2
- v2.5.1
- v2.5.0
- v2.4.6
- v2.4.5
- v2.4.4
- v2.4.3
- v2.4.2
- v2.4.1
- v2.4.0
- v2.3.10
- v2.3.9
- v2.3.8
- v2.3.7
- v2.3.6
- v2.3.5
- v2.3.4
- v2.3.3
- v2.3.2
- v2.3.1
- v2.3.0
- v2.2.0
- v2.1.6
- v2.1.5
- v2.1.4
- v2.1.3
- v2.1.1
- v2.1.0
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
This package is auto-updated.
Last update: 2026-09-17 02:22:49 UTC
README
C++ wrapper for Zend API
Requirements
- PHP 8.4 or later
- Linux/macOS/Windows
- GCC 9 or later (with C++17 support)
- Composer
Installation
Build libphpx.so
# Standard build (Release mode) cmake . make -j 4 sudo make install sudo ldconfig
Debug Mode (for troubleshooting)
# Clean previous builds cmake --build . --target clean # Configure Debug mode (includes debug symbols and runtime checks) cmake -DCMAKE_BUILD_TYPE=Debug . # Compile make -j 4 sudo make install sudo ldconfig
Debug Mode Features:
- ✅ Generates complete debug symbols
- ✅ Disables compiler optimizations for easier debugging
- ✅ Enables runtime error checking
- ✅ More detailed compilation output
Quick Start
Create a New Extension Project
mkdir test cd test composer require swoole/phpx vendor/bin/phpx init
Basic Usage Example
Here's a complete example demonstrating modern PHPX extension development:
#include "phpx_ext.h" // Include auto-generated arginfo header (generated by gen_stub.php) BEGIN_EXTERN_C() #include "your_extension_arginfo.h" END_EXTERN_C() using namespace php; using namespace std; // Method implementation using PHPX_METHOD macro PHPX_METHOD(MyClass, __construct) { // Initialize object properties _this.set("name", args[0].toString()); _this.set("value", args[1].toInt()); return nullptr; } PHPX_METHOD(MyClass, greet) { // Access object properties auto name = _this.get("name"); auto value = _this.get("value"); // Return formatted string return "Hello, " + name.toStdString() + "! Value: " + to_string(value.toInt()); } PHPX_METHOD(MyClass, processData) { // Work with Array type Array input = args[0]; Array result; // Iterate and transform for (auto &item : input) { result.append(item.value.toInt() * 2); } return result; } // Function implementation using PHPX_FUNCTION macro PHPX_FUNCTION(my_extension_func) { // Variant - universal type container Variant str_var = "Hello PHPX"; Variant int_var = 42; Variant float_var = 3.14159; // Array operations Array arr; arr.set("name", "PHPX"); arr.set("version", 8.2); arr.set("features", Array{"C++17", "Type-safe", "Modern API"}); // Object creation and method calls Object datetime = newObject("DateTime"); auto formatted = datetime.call("format", {"Y-m-d H:i:s"}); // Call PHP functions through the generic call API php::call("var_dump", {arr}); php::call("print_r", {datetime}); // File operations auto content = php::call("file_get_contents", {"/etc/hosts"}); if (content.isString()) { echo("File length: ", content.length(), "\n"); } // Array manipulation with references Array numbers{1, 2, 3, 4, 5}; numbers.sort(); numbers.appendValue(6); numbers.appendValue(7); numbers.appendValue(8); RETURN_STRING("PHPX Demo Completed!"); } // Extension entry point PHPX_EXTENSION() { Extension *ext = new Extension("my_extension", "1.0.0"); // Register lifecycle callbacks ext->onStart = [ext]() noexcept { // Register constants ext->registerConstant("MY_EXT_VERSION", 10000); // Register class with methods Class *c = new Class("MyClass"); c->addProperty("name", "", ZEND_ACC_PUBLIC); c->addProperty("value", 0, ZEND_ACC_PUBLIC); c->registerFunctions(class_MyClass_methods); // From arginfo header ext->registerClass(c); }; // Register the function table generated from the stub. ext->registerFunctions(ext_functions); // PHP info page configuration ext->info({"my_extension support", "enabled"}, { {"author", "Your Name"}, {"version", ext->version}, {"github", "https://github.com/your/repo"}, }); return ext; }
Key Features:
- PHPX_METHOD/PHPX_FUNCTION: Modern macros for cleaner code
- Extension/Class API: Object-oriented extension registration
- Lambda callbacks: Flexible lifecycle management with
onStart,onShutdown, etc. - Type-safe wrappers:
Variant,Array,Object,Stringclasses - Generic calls: Invoke PHP functions and methods with
php::call()andObject::call() - Auto-generated arginfo: Use
gen_stub.phpto generate type information
Generate ArgInfo & Function Entries
phpx init creates the CMake project, src/, include/, a PHPT smoke test,
and README in the current Composer project. It also copies the matching
gen_stub.php to build/ and run-tests.php to the project root from the PHP
development package, without requiring phpize:
composer require swoole/phpx
vendor/bin/phpx init
vendor/bin/phpx build
sudo vendor/bin/phpx install
sudo vendor/bin/phpx enable
After building, phpx install, phpx enable, and phpx disable copy the
module and update php.ini. init uses php-config from PATH; use
phpx init --php-config=/path/to/php-config initially or
phpx switch /path/to/php-config later to select another PHP installation.
Stub files belong in src/*.stub.php; generated *_arginfo.h files are written
next to their stubs and remain private implementation files. phpx install
publishes only C/C++ headers placed explicitly under include/, installing them
to $(php-config --include-dir)/ext/<extension-name>/. Headers under src/ are
never installed.
Build Your Extension
cd test cmake . make -j 4 make install
Load Your Extension
Edit php.ini and add:
extension=test.so
Test Your Extension
Create a test file test.php:
<?php echo hello_world() . "\n"; ?>
Run it:
php test.php
Expected output:
Hello, World!
Advanced Usage
1. Variant Type Usage
Variant is a universal type container that can hold any PHP value:
#include "phpx.h" using namespace php; // Create variants of different types Variant str_var = "Hello PHPX"; Variant int_var = 42; Variant float_var = 3.14159; Variant bool_var = true; Variant null_var; // Type checking if (str_var.isString()) { echo("String: ", str_var.toCString()); } if (int_var.isInt()) { echo("Integer: ", int_var.toInt()); } // Type conversion auto str = int_var.toString(); // Convert to string auto num = str_var.toInt(); // Convert to integer (0 if not numeric) // Comparison if (str_var.equals("Hello PHPX")) { echo("Match!"); } // Serialization Variant serialized = str_var.serialize(); Variant unserialized = serialized.unserialize();
2. Array Type Usage
Array provides a C++ wrapper for PHP arrays with rich functionality:
#include "phpx.h" using namespace php; // Create arrays Array arr; arr.set("name", "PHPX"); arr.set("version", 8.2); arr.set("features", Array{"C++17", "Type-safe", "Modern API"}); // Initialize with list Array numbers{1, 2, 3, 4, 5}; Array map{{"key1", "value1"}, {"key2", "value2"}}; // Access elements auto name = arr.get("name"); auto first = numbers[0]; // Check existence if (arr.exists("name")) { echo("Name exists"); } // Iterate array for (auto &item : arr) { echo(item.key, ": ", item.value, "\n"); } // Array operations arr.append("new_element"); // Add element arr.del("name"); // Remove element auto count = arr.count(); // Get count auto keys = arr.keys(); // Get all keys // Nested arrays Array nested; nested.set("level1", Array{ {"level2", Array{"deep_value"}} }); auto deep = nested.item("level1").item("level2"); // Reference for modification Array nums{5, 2, 8, 1, 9}; Reference ref = nums.toReference(); php::sort(ref); // Sort in place php::array_push(ref, 10, 11); // Push elements
3. Object Type Usage
Object wraps PHP objects and provides method calling capabilities:
#include "phpx.h" using namespace php; // Create object Object datetime = newObject("DateTime"); // Call methods auto formatted = datetime.call("format", {"Y-m-d H:i:s"}); echo("Current time: ", formatted.toCString()); // Set properties Object stdclass = newObject("stdClass"); stdclass.set("name", "test"); stdclass.set("value", 42); // Get properties auto name = stdclass.get("name"); auto value = stdclass.get("value"); // Check property existence if (stdclass.exists("name")) { echo("Property exists"); } // Create object with constructor arguments Object arrayObj = newObject("ArrayObject", { Array{1, 2, 3, 4, 5} }); // Call method and get result auto count = arrayObj.call("count"); echo("Count: ", count.toInt()); // Static method calls auto result = callStaticMethod("DateTime", "createFromFormat", { "Y-m-d", "2024-01-01" });
4. Calling PHP Functions
PHP functions are invoked through the generic php::call() API. Frequently used,
type-safe fast paths are available separately in php::fn through phpx_std.h.
#include "phpx.h" #include "phpx_std.h" using namespace php; Array data{{"name", "PHPX"}, {"version", 8.2}}; auto json = php::call("json_encode", {data}); auto decoded = php::call("json_decode", {json, true}); php::call("var_dump", {decoded}); // Optimized standard-library wrappers auto digest = php::fn::md5("hello");
5. Calling Built-in Classes
Use newObject(), Object::call(), and callStaticMethod() for PHP classes:
#include "phpx.h" using namespace php; Object redis = newObject("Redis"); redis.call("connect", {"127.0.0.1", 6379}); redis.call("set", {"name", "PHPX"}); auto name = redis.call("get", {"name"}); auto date = callStaticMethod("DateTime", "createFromFormat", { "Y-m-d", "2024-01-01" });
Documentation
For more detailed documentation, please check:
Examples
Check out the examples directory for more comprehensive examples including:
- Bloom filter implementation
- Queue data structure
- RocksDB integration
- GTK application
- And more!
Language
License
PHPX is open-sourced software licensed under the Apache License 2.0.
