# cpe **Repository Path**: kllxs_admin/cpe ## Basic Information - **Project Name**: cpe - **Description**: c++ 开发 php 帮助文件头 - **Primary Language**: C++ - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-17 - **Last Updated**: 2026-05-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PHP++ — PHP 扩展开发框架 C++ 单头文件框架,让 PHP 扩展开发如同写 PHP 函数一样简单。 **一行 `Func(...)` = 一个函数**,无需手写函数表、参数信息、模块入口。 ## 快速开始 ```cpp #include "php++.h" Func(add, t_int, Arg(t_int, "a") Arg(t_int, "b") ){ RetInt(GetArgInt(1) + GetArgInt(2)); } Module("example", "1.0.0", NULL) ``` PHP 调用: ```php dl('example.dll'); echo add(10, 20); // 30 ``` 编译:`peb -dir 8.5.6 -out example.dll -c example.cpp` --- ## 类型系统 | 宏 | PHP 类型 | 说明 | |---|---------|------| | `t_int` | `int` | 整数 | | `t_float` | `float` | 浮点数 | | `t_str` | `string` | 字符串 | | `t_bool` | `bool` | 布尔值 | | `t_array` | `array` | 数组 | | `t_object` | `object` | 对象 | | `t_func` | `callable` | 可调用 | | `t_void` | `void` | 无返回值 | 枚举底层类型:`t_enum_int` / `t_enum_str` / `t_enum_float` / `t_enum_bool` ```cpp // PHP 类型封装 p_int a = PhpInt(100); p_str b = PhpStr("hello"); p_float c = PhpFloat(3.14); p_bool d = PhpBool(true); // PHP → C 转换 int x = CInt(a); const char* s = CStr(b); double f = CFloat(c); bool v = CBool(d); ``` --- ## 函数定义 ### 参数获取 ```cpp Func(demo, t_int, Arg(t_int, "a") Arg(t_str, "name") ){ int a = GetArgInt(1); // 强类型,不匹配抛 TypeError const char* s = GetArgStr(2); float f = GetArgFloat(3); bool b = GetArgBool(4); RetInt(a); } ``` | 类型 | 无默认值 | 带默认值 | |------|---------|---------| | int | `GetArgInt(n)` | `GetArgIntDfl(n, dfl)` | | string | `GetArgStr(n)` | `GetArgStrDfl(n, dfl)` | | float | `GetArgFloat(n)` | `GetArgFloatDfl(n, dfl)` | | bool | `GetArgBool(n)` | `GetArgBoolDfl(n, dfl)` | | array | `GetArgArr(n)` | `GetArgArrDfl(n, dfl)` | | object | `GetArgObj(n)` | `GetArgObjDfl(n, dfl)` | | callable | `GetArgFunc(n)` | — | | 通用 | `GetArg(n)` | — | ### 返回值 ```cpp RetInt(42); RetStr("hello"); RetFloat(3.14); RetBool(true); RetNull(); RetArr(arr); RetObj(obj); RetThis(); // 链式调用 ``` --- ## 调用 PHP 内置函数 `PhpCall("函数名", &返回值, 参数1, 参数2, ...)` — 支持 0~5 个参数,自动类型适配。 ```cpp Func(my_strlen, t_int, Arg(t_str, "s")) { zval ret; PhpCall("strlen", &ret, GetArgStr(1)); RetInt(Z_LVAL(ret)); zval_ptr_dtor(&ret); // 记得释放返回值! } Func(read_file, t_str, Arg(t_str, "path")) { zval ret; PhpCall("file_get_contents", &ret, GetArgStr(1)); RetStr(Z_STRVAL(ret)); zval_ptr_dtor(&ret); } Func(json_work, t_str, Arg(t_arr, "data")) { zval encoded, arr_zv; ZVAL_ARR(&arr_zv, GetArgArr(1).raw()); PhpCall("json_encode", &encoded, &arr_zv); // → JSON string RetStr(Z_STRVAL(encoded)); zval_ptr_dtor(&encoded); } ``` **参数直接传 C 类型**,自动转为 zval:`int` / `const char*` / `double` / `bool` / `zval*` | 注意事项 | |---------| | 返回值用完必须 `zval_ptr_dtor(&ret)` | | 参数所有权由 `call_user_function` 接管,无需手动释放 | --- ## 回调函数 ```cpp Func(myCallback, t_int, Arg(t_func, "func")) { p_func func = GetArgFunc(1); func.add(10).add("hello").call(); // 链式传参 RetFuncInt(func); // 提取返回值 } ``` PHP 端: ```php echo myCallback(function($a, $b) { var_dump($a, $b); // int(10), string(5) "hello" return 111; }); // 111 ``` **PHP→C 回调桥接**:用 `PhpCbDup` 堆拷贝 callable,配合无捕获 lambda(自动转 C 函数指针),数据走 `void*`: ```cpp zval* cb = PhpCbDup(_C(1)); some_c_api(cb, [](int x, const char* y, void* ctx) { p_func((zval*)ctx).add(x).add(y).call(); }); ``` --- ## 数组操作 ```cpp Func(arr_demo, t_array, Arg(t_array, "arr")) { p_arr arr = GetArgArr(1); arr.each([&](zval* key, zval* val) { if (PType(key) == t_int && CInt(key) == 0) { PhpArrSet(arr, key, "updated"); } if (PType(val) == t_str) { char buf[100]; sprintf(buf, "Hello, %s!", CStr(val)); PhpArrSet(arr, key, buf); } if (PType(val) == t_array) { p_arr child = PhpArr(val); child.each([&](zval* ck, zval* cv) { PhpArrSet(child, ck, "nested"); }); } }); PhpArrSet(arr, "status", 100); // 字符串键 PhpArrSet(arr, arr.size(), "appended"); // 数字索引追加 RetArr(arr); } ``` ### zval* 工具函数(遍历回调中使用) | 函数 | 说明 | |------|------| | `PType(v)` | 获取类型 | | `CInt(v)` / `CStr(v)` / `CFloat(v)` / `CBool(v)` | 类型转换 | | `PhpArr(v)` / `PhpObj(v)` | → p_arr / p_obj | ### PhpArrSet 重载 ```cpp PhpArrSet(arr, key_zval, value); // zval* 键(遍历时) PhpArrSet(arr, "key", value); // 字符串键 PhpArrSet(arr, index, value); // 数字索引 // value 支持: const char* / zend_long / int / double / bool ``` ### arr 实例方法 | 方法 | 说明 | |------|------| | `each(fn)` | 遍历键值对 `(zval* key, zval* val)` | | `values(fn)` | 只遍历值 | | `pairs(fn)` | 遍历 `(索引, 值)` 对 | | `count()` / `size()` | 元素数量 | | `add(val)` / `set(key, val)` | 增/改元素 | | `raw()` | 获取原始 `HashTable*` | --- ## 对象操作 ```cpp Func(obj_demo, t_object, Arg(t_object, "obj")) { p_obj obj = GetArgObj(1); p_val v = PhpObjGet(obj, "name"); if (PType(v) == t_str) { char buf[100]; sprintf(buf, "Hello, %s!", CStr(v)); PhpObjSet(obj, "name", buf); } RetObj(obj); } ``` | 函数 | 说明 | |------|------| | `PhpObjGet(obj, "prop")` | 读取属性 → `zval*` | | `PhpObjSet(obj, "prop", v)` | 设置属性(支持 `const char*`/`int`/`double`/`bool`) | | `Object::create("ClassName")` | 创建对象(默认 `stdClass`) | | `This()` | 获取当前 `$this` | --- ## 类定义 ```cpp Class(MyClass) Method(MyClass, __construct, t_void, Arg(t_int, "val")) { c_val = GetArgInt(1); } Method(MyClass, getValue, t_int) { RetInt(c_val); } Method(MyClass, setValue, t_object, Arg(t_int, "val")) { c_val = GetArgInt(1); RetThis(); // 返回 $this 支持链式 } StaticMethod(MyClass, create, t_int, Arg(t_int, "val")) { RetInt(GetArgInt(1) * 10); } ``` PHP 端: ```php $obj = new MyClass(10); echo $obj->getValue(); // 10 echo $obj->setValue(20)->getValue(); // 20 echo MyClass::create(5); // 50 ``` --- ## 枚举定义 ```cpp // 整数 PhpEnum(Status, t_int) EnumCase(Status, PENDING, 0) EnumCase(Status, ACTIVE, 1) EnumCase(Status, INACTIVE, 2) // 字符串 PhpEnum(Color, t_str) EnumCase(Color, RED, "red") EnumCase(Color, GREEN, "green") EnumCase(Color, BLUE, "blue") // 浮点 / 布尔同理 PhpEnum(Temperature, t_float) EnumCase(Temperature, HOT, 35.5) ``` > 值类型自动推断 — `0` → int, `"red"` → string, `35.5` → float, `true` → bool --- ## 编译与加载 ```bash # 编译(项目内置 MSVC + PHP SDK,无需额外安装) peb -dir 8.5.6 -out example.dll -c example.cpp # 多文件 peb -dir 8.5.6 -out example.dll -c a.cpp b.cpp c.cpp ``` ```php