How PHPX 2.0 Lets You Write C++ with PHP‑Like Syntax
PHPX 2.0 is a re‑engineered extension library that lets developers write C++ code using PHP‑style dynamic syntax, offering safe memory handling, operator overloading, var‑keyword typing, and seamless integration with Composer and CMake for building high‑performance PHP extensions.
PHPX 2.0 is a redesign of the original PHPX 1.0 ZendAPI wrapper created by the Shiwotech team in 2016. The new version removes legacy code, adds a garbage‑collected memory model, and provides a PHP‑like programming experience for writing C++ extensions safely without manual memory management.
New Syntax
The library leverages PHP’s dynamic typing and garbage collection to allow C++ code to be written as if it were PHP. Variables are declared with the var keyword and can hold any type (string, array, integer, float, boolean, etc.).
var a = "hello world";
var b = 2025;
var c = a;
b += 100; // arithmetic
a.append(b); // string concatenation
var d = b << 3; // bit shift
if (a == c) {}
var e = {"php", "swoole", "is", "best"};
var f = {{"key", "value"}, {"key2", 2024.08}};Operator Overloading
PHPX 2.0 overloads arithmetic, increment/decrement, assignment, bitwise, and comparison operators so that they behave exactly like their PHP equivalents. When types mismatch, automatic conversion is performed.
Arithmetic operations
Increment/Decrement
Assignment
Bitwise operations
Comparisons (==, >, <=, !=, etc.)
Exception: C++ does not have the ** operator; use Variant::pow() instead. The string concatenation operator . maps to Variant::append() or Variant::concat() .
Function Calls
Functions can be called directly using the new syntax. Example of reading a file and checking a directory:
var file = "/tmp/file.txt";
var rs = file_get_contents(file);
var_dump(rs);
var_dump(is_dir({"/tmp-not-exists"}));CURL Example
auto ch = curl_init();
auto url = "https://www.gov.cn/";
Array headerArray = {{"User-Agent: Mozilla/5.0 ..."}, {"Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"}};
curl_setopt(ch, CURLOPT_URL, url);
curl_setopt(ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt(ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt(ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt(ch, CURLOPT_HTTPHEADER, headerArray);
auto output = curl_exec(ch);
curl_close(ch);
ASSERT_FALSE(output.empty());
ASSERT_TRUE(str_contains(output, "中国").toBool());Hash Example
constexpr int l = 1024;
auto rdata = random_bytes({l});
ASSERT_EQ(rdata.length(), l);
auto hash1 = sha1(rdata);
auto hash2 = hash({"sha1"}, rdata);
ASSERT_TRUE(hash1 == hash2);Object Methods
Classes can be defined in C++ and exposed to PHP. The following snippet shows a simple class with a method that returns a string:
Redis redis{};
Array context{};
var ref_context = context.toReference();
var rv = redis.connect("127.0.0.1", 6379, 2.5, null, 0, 0, ref_context);
ASSERT_TRUE(rv.toBool());
var val = "hello phpx";
var key = "phpx_test_key";
redis.set(key, val);
var val2 = redis.get({key});Predefined Constants and Basic Functions
Constants such as PHP_VERSION and PHP_OS are generated automatically. Core functions include include/require, global, eval, throwException, catchException, echo, and error.
Array and String Operations
Arrays can be accessed with the familiar bracket syntax, and strings support in‑place modification via append and non‑mutating concatenation via concat:
// Write associative array
Array arr;
arr["hello"] = 1999;
arr["world"] = "swoole";
// Write indexed array
Array arr2;
arr2[0] = 1;
arr2[1] = 99;
// Read
var b = arr["hello"];
var c = arr2[0]; var a = "abc";
a.append(" hello"); // modifies a
var b = a.concat(" hello"); // returns new stringInstallation
PHPX 2.0 uses Composer and CMake for package management and building. The typical workflow is:
composer create-project swoole/phpx-ext myext
cd myext
./phpx build # compile
./phpx setup # install to extension‑dir
./phpx enable # enable the extension
./phpx disable # disable the extensionAlternatively, run cmake . && make -j 8 manually.
Core Mechanisms
Memory Layout
The internal Variant structure now matches the PHP zval layout exactly, occupying only 16 bytes:
sizeof(zval) == sizeof(Variant)Reference Counting
All variables are managed by built‑in reference counting, eliminating manual new/delete. Small scalar types (< 8 bytes) are passed by value, resources are opaque objects passed by reference, and strings/arrays use copy‑on‑write semantics.
// String copy‑on‑write
var s = "hello world";
var a = s; // shallow copy, ref count +1
s.append("
"); // s detaches from a
// Array copy‑on‑write
var c = {1,2,3,4};
var d = c; // shallow copy
c.append(5); // c detaches from dGarbage Collection
PHP’s GC automatically detects cyclic references in complex objects and arrays, freeing memory safely.
Reference & Dereference
References are created with the & operator and dereferenced with *:
Array array;
auto ref = &array;
array_push(ref, "hello");
auto real_array = *ref;Safety Tips
Avoid manual new/delete in C++; rely on the built‑in reference counting.
Do not use the raw ZendAPI directly, as it may corrupt reference counts.
Encapsulate C++ object pointers as Resource types for safe passage.
Prefer the var type over shared_ptr to avoid duplicate reference‑count mechanisms.
Testing and Performance
The new release includes extensive unit tests with coverage reaching 96%:
Performance optimizations for PHPX_FUNCTION and PHPX_METHOD eliminate hash look‑ups and add memory caching, making the call overhead comparable to native PHP extensions.
The Variant type now mirrors zval in both size and speed, achieving parity with the original ZendAPI implementation.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
