vphp 是一个用 V 语言编写 PHP 扩展的绑定与编译框架。
它的目标不是重做一套 PHP 生态,而是让我们:
- 用 V 编写 PHP 扩展函数、类、接口、枚举和运行时逻辑
- 通过编译器自动生成 Zend glue code
- 在 V 侧直接调用 PHP 现有函数、类、对象、静态方法、属性和常量
一句话说:
vphp= PHP 的 Zend Binding for V + 一套面向 PHP 扩展开发的编译器与运行时
项目目前已经打通并持续有测试覆盖的能力包括:
- PHP 全局函数导出:
@[php_function] - PHP 类导出:
@[php_class] - PHP 方法导出:
@[php_method] - PHP 抽象类 / 抽象方法:
@[php_abstract] - PHP 接口:
@[php_interface] - V
implements-> PHPimplements - PHP enum 风格导出:
@[php_enum] - class constant shadow:
@[php_const: ...] - class static property shadow:
@[php_static: ...] Context参数/返回值 APIZVal/Val[T]转换V -> PHPinterop:php_fn(name)php_class(name)ZVal.call(...)ZVal.method(...)ZVal.construct(...)ZVal.prop(...)ZVal.static_method(...)ZVal.static_prop(...)ZVal.@const(...)
当前测试状态:
36 PASS1 SKIP0 FAIL
vphpext/
README.md
vphp/ # 运行时、Zend 绑定、编译器
compiler/ # V -> PHP bridge 编译器
zend/ # Zend 原生 API / bridge API 绑定
context.v # PHP -> V 调用上下文
zval.v # Zend zval 的 V 封装
val.v # V 语义值模型
interop.v # V -> PHP interop 入口
object.v # vphp 对象运行时辅助
v_php_ext/ # 示例扩展、构建脚本与测试
build.v
functions.v
article.v
tests/
flowchart LR
A["V user code"] --> B["vphp compiler"]
B --> C["php_bridge.h / php_bridge.c / bridge.v"]
C --> D["Zend extension (.so)"]
D --> E["PHP runtime"]
E --> F["vphp runtime (Context / ZVal / Interop)"]
更具体一点:
-
vphp/compiler/- 负责编译 V 源码中的导出元信息
- 生成 C bridge 和 V glue
-
vphp/zend/- 负责 Zend 类型、常量、原生 API 与
vphp_*bridge API 的 FFI 绑定
- 负责 Zend 类型、常量、原生 API 与
-
vphp/根目录运行时Context:PHP 调 V 时的调用上下文ZVal:C.zval的完整 wrapperVal[T]:V 语义值模型interop:V 调 PHP 的统一入口
在 v_php_ext/config.v 中:
module main
import vphp
const ext_config = vphp.ExtensionConfig{
name: 'vphptest'
version: '0.1.0'
description: 'PHP Bindings for V'
}module main
@[php_function]
fn v_add(a i64, b i64) i64 {
return a + b
}PHP 侧就可以直接调用:
echo v_add(1, 2);module main
import vphp
@[php_function]
fn v_logic_main(ctx vphp.Context) {
name := ctx.arg[string](0)
ctx.return_string('Hello, ${name}')
}module main
@[heap]
@[php_class]
struct Article {
pub mut:
title string
}
@[php_method]
pub fn (a &Article) construct(title string) {
unsafe {
mut self := a
self.title = title
}
}
@[php_method]
pub fn (a &Article) get_formatted_title() string {
return '[Article] ${a.title}'
}version := vphp.php_fn('phpversion').call([]).to_string()或直接 typed:
length := vphp.php_fn('strlen').call_v[int]([
vphp.ZVal.new_string('codex'),
])!obj := vphp.php_class('DateTime').construct([
vphp.ZVal.new_string('now'),
])
formatted := obj.method('format', [
vphp.ZVal.new_string('c'),
]).to_string()进入示例扩展目录:
cd /Users/guweigang/Source/vphpext/v_php_ext
make build成功后会生成:
php_bridge.hphp_bridge.cbridge.vvphp_ext_vphptest.cv_php_ext.so
如果你已经提前跑过 vphp 编译器,并且仓库里已有生成的中间 C 文件,也可以直接跳过 compile 阶段,只做最终链接:
cd /Users/guweigang/Source/vphpext/v_php_ext
make ext现在的构建入口是:
make build- 完整流程:
vphp compile + 代码生成 + V 转 C + GCC 链接
- 完整流程:
make ext- 只使用仓库中现成的
vphp_ext_*.c/php_bridge.c/php_bridge.h做最终链接
- 只使用仓库中现成的
make test- 先完整构建,再运行
phpt
- 先完整构建,再运行
cd /Users/guweigang/Source/vphpext/v_php_ext
make test当前测试覆盖了:
- 基础函数导出
Context参数解析- map/list/struct 转换
- 类、继承、接口、抽象类
- class constant / static property shadow
- enum 导出
- closure / resource / globals / task
php_fn/php_class/ object/static/const interop- typed interop 与 typed object restore
从 vphp/compiler/README.md 开始。
推荐顺序:
这个项目当前有几个明确的设计原则:
vphp保持通用
- 编译器、运行时、Zend 绑定、值模型都收敛在
vphp/
- 示例与框架实验放在
v_php_ext/
- 避免把上层实验逻辑污染到底层 binding
- 优先复用 PHP 生态,而不是在 V 里重造一切
- 这也是
interop.v存在的原因
- 编译器分层明确
reprparserlinkerbuilderexportc_emitterv_glue
当前还有一些有意保守的地方:
@[php_enum]目前导出为 enum-style final class,不是 PHP 8.1 native enum object 语义to_object[T]()只适用于vphp导出的对象,不适用于普通 PHP userland/internal 对象- class static property 当前是
shadow singleton + sync语义 - interop 层已经比较完整,但对象/类型系统还有继续细化空间
如果你想做这些事情,vphp 会很适合:
- 用 V 给 PHP 写高性能扩展
- 给现有 PHP 项目暴露 V 计算能力
- 研究 Zend 扩展与 V 语言的桥接
- 构建一个有编译器、有运行时、有测试体系的 PHP Binding
如果你准备继续往下读,我推荐先从这三个文件开始: