# Box 机制使用指南 ## 📌 核心概念 Box 是 PHPX 编译器提供的 C++ 对象封装机制,允许将 C++ 对象安全地传递给 PHP 层使用。 ## ✅ 正确的使用方法 ### 1. C++ 类定义 **必须继承自 `Box` 类:** ```cpp #include using namespace php; class TetrisBox : public Box { public: int board[20][10]; int score; bool gameOver; TetrisBox() : score(0), gameOver(false) { memset(board, 0, sizeof(board)); } void reset() { score = 0; gameOver = false; memset(board, 0, sizeof(board)); } }; ``` ### 2. 创建并返回 Box 对象 **使用 `{new ClassName()}` 语法:** ```cpp var php_tetris_new() { return {new TetrisBox()}; // ✅ 正确:使用花括号包装 new 表达式 } ``` ❌ **错误做法:** ```cpp // 错误 1:直接使用 var() 包装指针 var php_tetris_new() { auto* state = new TetrisBox(); return var(state); // ❌ 这不是 Box 类型 } // 错误 2:返回整数 ID Int php_tetris_new() { return 1; // ❌ 失去了 Box 的意义 } ``` ### 3. 从 Variant 提取 Box 对象 **使用 `box.toBox()` 方法:** ```cpp void php_tetris_reset(var box) { auto tetris = box.toBox(); // ✅ 正确:使用 toBox 模板方法 tetris->reset(); } Int php_tetris_get_score(var box) { auto tetris = box.toBox(); // ✅ 正确 return tetris->score; } ``` ❌ **错误做法:** ```cpp // 错误:直接使用 ptr() 获取指针 void php_tetris_reset(var box) { auto* state = (TetrisBox*)box.ptr(); // ❌ 不安全,不是正确的 Box 转换方式 state->reset(); } ``` ### 4. Stub 文件声明 **使用 `mixed` 类型表示 Box 对象:** ```php game = tetris_new(); // 接收 Box 对象 } public function getScore(): int { return tetris_get_score($this->game); // 传递 Box 对象给 C++ } public function reset(): void { tetris_reset($this->game); // 传递 Box 对象给 C++ } } ``` ## 🔑 关键要点总结 ### 类型映射规则 | C++ 类型 | Stub 类型 | PHP 类型 | 说明 | |---------|----------|---------|------| | `var` | `mixed` | `mixed` | Box 对象或任意类型 | | `Variant` | `mixed` | `mixed` | 同上(var 是 Variant 的别名) | | `Int` | `int` | `int` | 整数 | | `Bool` | `bool` | `bool` | 布尔值 | | `String` | `string` | `string` | 字符串 | | `Array` | `array` | `array` | 数组 | ### Box 使用三步曲 1. **定义类**:继承自 `Box` ```cpp class MyBox : public Box { ... }; ``` 2. **创建对象**:使用 `{new MyBox()}` 返回 ```cpp var php_my_new() { return {new MyBox()}; } ``` 3. **提取对象**:使用 `box.toBox()` ```cpp void php_my_method(var box) { auto obj = box.toBox(); obj->doSomething(); } ``` ## 📝 完整示例 ### C++ 实现 (tetris.cc) ```cpp #include #include using namespace php; class TetrisBox : public Box { public: int score; bool gameOver; TetrisBox() : score(0), gameOver(false) {} void reset() { score = 0; gameOver = false; } }; // 创建游戏实例 var php_tetris_new() { return {new TetrisBox()}; } // 重置游戏 void php_tetris_reset(var box) { auto tetris = box.toBox(); tetris->reset(); } // 获取分数 Int php_tetris_get_score(var box) { auto tetris = box.toBox(); return tetris->score; } // 检查游戏结束 Bool php_tetris_is_game_over(var box) { auto tetris = box.toBox(); return tetris->gameOver; } ``` ### Stub 文件 (tetris.stub.php) ```php (); // 安全的类型转换 } ``` ## 🎯 最佳实践 1. **始终使用 `toBox()`**:这是类型安全的转换方法 2. **Stub 中使用 `mixed`**:对应 C++ 的 `var`/`Variant` 类型 3. **PHP 中使用 `mixed` 类型提示**:保持类型一致性 4. **添加空指针检查**(可选): ```cpp void php_tetris_reset(var box) { if (!box.isResource()) { throw Exception("Invalid game object"); } auto tetris = box.toBox(); tetris->reset(); } ``` ## 📚 参考资料 - `examples/prime` - Box 机制的标准示例 - `examples/tetris` - 本项目的完整实现 - PHPX 编译器文档 --- **记住:正确的 Box 使用方式是 `box.toBox()`,而不是 `box.ptr()`!**