使用 go 和仓颉重构了整个 PHP - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
2024
V2EX    分享创造

使用 go 和仓颉重构了整个 PHP

  •  1
     
  •   2024 73 天前 4400 次点击
    这是一个创建于 73 天前的主题,其中的信息可能已经有所发展或是发生改变。

    折言(origami-lang)

    折言(origami-lang) 是一门创新性的融合型脚本语言,深度结合 PHP 的快速开发基因与 Go 的高效并发模型。同时还有部分 go 、ts 习惯引入。

    当前状态

    当前未对代码分支进行任何优化,性能尚未优化。 请作为一个工具使用,请勿用于生产环境。

    核心特征

    Go 反射集成

    • 便捷注册: 一键将 Go 函数注册到脚本域 vm.RegisterFunction("add", func(a, b int) int { return a + b })
    • 类反射: 自动将 Go 结构体转换为脚本类 vm.RegisterReflectClass("User", &User{})
    • 零配置: 无需手动编写包装代码,自动处理类型转换
    • 构造函数: 支持命名参数 $user = new User(Name: "Alice")
    • 方法调用: 直接调用 Go 结构体的公开方法 $user->SetName("Bob")

    语法融合

    • PHP 兼容: 支持大部分 PHP 语法
    • Go 并发: spawn 关键字启动协程
    • 类型系统: 支持类型声明 int $i = 0 和可空类型 ?string

    特殊语法

    • HTML 内嵌: 支持直接内嵌 HTML 代码块
    • 字符串插值: "Hello {$name}""@{function()}" 语法
    • 鸭子类型: like 关键字进行结构匹配
    • 中文编程: 支持中文关键字 函数输出
    • 参数后置: 支持 function($param: type) 语法
    • 异步执行: spawn 关键字启动异步协程
    • 泛型类: 支持 class DB<T> 泛型语法

    数组方法

    • 链式调用: $array->map()->filter()->reduce()
    • 函数式编程: map(), filter(), reduce(), flatMap()
    • 查找方法: find(), findIndex(), includes()

    面向对象

    • 类继承: 支持单继承和接口实现
    • 类型检查: instanceoflike 操作符
    • 父类访问: parent:: 语法

    示例

    Go 反射集成

    // 定义 Go 结构体 type Calculator struct { Name string } func (c *Calculator) Add(a, b int) int { return a + b } func (c *Calculator) GetName() string { return c.Name } // 注册到脚本域 vm.RegisterReflectClass("Calculator", &Calculator{}) 
    <?php // 在脚本中使用 $calc = new Calculator(Name: "MyCalc"); echo $calc->GetName(); // 输出: MyCalc echo $calc->Add(5, 3); // 输出: 8 ?> 

    函数注册

    // 注册 Go 函数 vm.RegisterFunction("add", func(a, b int) int { return a + b }) vm.RegisterFunction("isEven", func(n int) bool { return n%2 == 0 }) 
    <?php // 脚本中调用 $result = add(5, 3); // 返回 8 $even = isEven(4); // 返回 true ?> 

    基础语法

    int $count = 0; string $name = "World"; echo "Hello {$name}"; function greet(string $name): string { return "Hello " . $name; } 

    参数后置语法

    function div($obj) { return "<div>" + $obj->body + "</div>"; } function span($obj) { return "<span>" + $obj->body + "</span>"; } $html = div { "body": span { "body": "内容", } } 

    泛型类

    class Users { public $name = ""; } class DB<T> { public $where = {}; public function where($key, $value) { $this->where[$key] = $value; return $this; } public function get() { return [new T()]; } } $list = DB<Users>()->where("name", "张三")->get(); 

    异步协程

    function fetchData($url: string): string { // 模拟网络请求 sleep(1); return "Data from " . $url; } // 启动异步协程 spawn fetchData("https://api.example.com"); echo "Main thread continues...\n"; 

    HTML 内嵌

    $cOntent= <div class="container"> <h1>{$title}</h1> <p>This is embedded HTML</p> </div>; 

    数组操作

    $numbers = [1, 2, 3, 4, 5]; $doubled = $numbers->map(($n) => $n * 2); $evens = $numbers->filter(($n) => $n % 2 == 0); 

    中文编程

    函数 用户(名称) { 输出 名称; } 用户("张三"); 

    快速开始

    git clone https://github.com/php-any/origami.git cd origami go build -o origami . ./origami script.php 

    文档

    讨论群

    折言讨论群二维码

    许可证

    MIT 许可证

    第 1 条附言    72 天前
    49 条回复    2025-08-25 16:12:13 +08:00
    twig
        1
    twig  
       72 天前
    链接不中啊
    putaozhenhaochi
        2
    putaozhenhaochi  
       72 天前
    $做变量开头 手打的不累吗
    imdong
        3
    imdong  
       72 天前 via iPhone
    U.14 ,PHP 成前端语言了
    imdong
        4
    imdong  
       72 天前 via iPhone
    2024
        5
    2024  
    OP
       72 天前
    2024
        6
    2024  
    OP
       72 天前
    @putaozhenhaochi #2 支持没有美元符号,可以看中文编程部分,甚至支持注册关键字,你把它当成 java 用都行
    2024
        7
    2024  
    OP
       72 天前
    @imdong #3 编译成 WebAssembly ,完全可以当 js 用也不是不行,支持这么多 UI 友好语法,主要是考虑老 php 不能写桌面 UI ,但是 go 版本完全可以写
    sssxyd
        8
    sssxyd  
       72 天前
    点个星,很棒的项目,不管有没有用
    ferock
        9
    ferock  
    PRO
       72 天前
    go 对 php 翻译?
    2024
        10
    2024  
    OP
       72 天前
    @ferock #9 不是,而是用 go 写一门新的语言,只是以 php 作为蓝本,如果不写$符号,当成 js 、java 写也不是不可以。比如字符串、数组操作直接用 js 命名实现,注解用 java 方式实现
    strobber16
        11
    strobber16  
       72 天前 via Android
    我还以为你用 go 写了一遍 php 解释器呢
    2024
        12
    2024  
    OP
       72 天前
    @strobber16 #11 也可以这里理解啊,只是没有全部兼容 php 语法,更像是 py 新版本不兼容老版本的更新
    qxmqh
        13
    qxmqh  
       72 天前
    看得头晕。
    panlatent
        14
    panlatent  
       72 天前
    解决了什么问题?
    qW7bo2FbzbC0
        15
    qW7bo2FbzbC0  
       72 天前   1
    “后来这教授的一个学生去了 Facebook ,帮他们做 HipHop ,一个从 PHP 到 C++ 的“编译器”。其实这种“源到源”编译器做起来不算难,但给 PHP 这样劣质的语言做编译器,实在是狗血的工作,繁琐而头痛。没有任何理论价值不说,在工业界有什么价值也难说。我的一个前同事曾经对 Facebook 的这个项目发表了一个尖锐而幽默的评价:“Facebook 现在不但给母猪涂上了口红,而且真的开始 f.. 它了!”

    https://www.yinwang.org/blog-cn/2019/12/24/compilers
    qW7bo2FbzbC0
        16
    qW7bo2FbzbC0  
       72 天前
    创意很好,应该是个 php 爱好者,技术力也不错,点赞
    dusu
        17
    dusu  
       72 天前 via iPhone
    项目是不错,优化了 php 语法诟病
    虽然可以用 go 生态,但基本只能自己撸
    没法延用 php 生态
    而且没有 jit 之类的性能话基本上也没太大保障
    OP 使用场景有点堪忧啊
    2024
        18
    2024  
    OP
       72 天前
    @panlatent #14 解决楼下提出的问题,php 很劣质,所以升级它。
    2024
        19
    2024  
    OP
       72 天前
    @dusu #17 性能已经比 php8.3 好了,自己运行下 performance_test.cjp 看结果。go 生态直接用, 对多封装一个函数或类
    redbule
        20
    redbule  
       72 天前
    和仓颉有啥关系?
    2024
        21
    2024  
    OP
       72 天前
    @redbule #20 因为我还有一个仓颉的版本
    Dlad
        22
    Dlad  
       72 天前
    不是,你来真的啊
    cs8425
        23
    cs8425  
       72 天前
    op 这东西让我想到 frankenphp 这个专案...
    https://frankenphp.dev/cn/
    2024
        24
    2024  
    OP
       72 天前
    @cs8425 #23 它是嵌入官方 php 解释器,然后 go 和 php 经过进程间通讯,性能可能比 php-fpm 快几倍,但是快不过 swoole 和 webmen 等没有代理层的框架。业务还是单进程模式,受 zend 接口限制
    Georgedoe
        25
    Georgedoe  
       72 天前
    还能这样语法杂交啊? 看的头都晕了
    panlatent
        26
    panlatent  
       72 天前
    @2024 #18

    如果作为一个玩票性质的项目,大概率是技养想“发明”一个编程语言或写一个 Parser 。作为一个有一定完成度的项目,给你个赞。

    如果作为一个真正可用的工具,我认为你没有解决任何问题。觉得 PHP 劣质的人绝不会不会发明另一种 PHP 。现实是任何企图从 PHP 改进分化的项目,大大小小都失败了,反而是 Roadrunner ,Frankenphp 这类强化 PHP 生态的项目才能跟 PHP 共同进步。

    如果没有任何的痛点,就算市面上所有的语法糖被你全部实现,也没有实际用处,就只能是一个适合你自己的 DSL 。
    2024
        27
    2024  
    OP
       72 天前
    @panlatent #26 现在解决的是 php 多线程、异步、GUi 友好,连接池、性能问题。生态问题呢,未来在依赖管理里引入 go 的库,我一键给你生成脚本域类不行吗?那你觉得怎么样的问题才算痛点呢,或者也能解决也不一定。集思广益。
    panlatent
        28
    panlatent  
       72 天前
    @2024 #27 痛点这个倒是没法给你建议,因为每个人的痛点不尽相同。PHP 于我而言不需要异步和多线程,性能也不是问题,能快速开发才是第一要务。所以我比较侧重 DX 和 生态。另外你说的东西,每一样都有一个流行的解决方案,你提供的东西不足以打动我抛弃这些。最后你开发开发就会发现,你发明了另一种 PHP / HHVM / Go ,在那之前如何保持充沛的动力去开发也是挺现实的困难,所以我的建议是一定要围绕真正去解决问题去开发。 当然,这些积累也可能某一天成为一个成功项目的基石,但我不太看好,编程语言现在还是有点卷,何况 AI 来了。
    redbule
        29
    redbule  
       72 天前
    @2024 #21 牛的
    stabc
        30
    stabc  
       72 天前
    我认为 PHP 最大的优势是他的“无服务器”特性,也就是每个请求开始到结束,所有东西都是这个请求独占的,请求之间绝对隔离,这使 web 开发异常简单。没有任何其他语言有这个特性。如果抛开这个特性,那还不如忘记 PHP,专注写一门新语言。
    2024
        31
    2024  
    OP
       72 天前
    @stabc #30 没有抛弃,一个实现下上下文管理类就能做到的事情
    SethShi
        32
    SethShi  
       72 天前
    @panlatent #26 如果真心想要多线程, 异步, GUI 友好, 连接池, 性能问题, 我的建议是给官方提交代码
    多线程, 连接池, 性能问题 官方有解决方案, swoole, roadrunner, workman 都可以
    GUI 友好直接去用 electron / flutter / android, 不要尝试一个语言做所有事情, 尝试的人都失败了
    stabc
        33
    stabc  
       72 天前
    @2024 当然有实现方式,但我说的是过程。用 context 就和 node,go 语言这些没区别了。PHP 的优势就是可以省去这个心智负担,整个代码就相当于给用户跑一个脚本,比如错误处理,程序中断等都极其简单粗暴。
    stabc
        34
    stabc  
       72 天前
    PHP 目前我认为最大的瓶颈是 FPM 的数量。如果你能把他做成像 goroutine 那种能开成千上万的 FPM,绝对是行业爆炸级新闻
    2024
        35
    2024  
    OP
       72 天前
    @stabc #33 你理解错了,我说的上下文是模拟虚拟机层的,用于存储已有的语法节点的对象,把它对齐后,代码缓存和状态就没有了
    2024
        36
    2024  
    OP
       72 天前
    @seth19960929 #32 你说的哪些库是多进程方案,不是他们不想,是 php 底层实现很难做到。
    2024
        37
    2024  
    OP
       72 天前
    @stabc #34 goroutine 会处理每个请求,请求开始地方设置一个宏处理,插入一个修改函数级别的上下文,并对 vm 克隆隔离就能实现请求内变量和新加载的文件不会影响到其他请求。
    stabc
        38
    stabc  
       72 天前
    @2024 那你怎么启动一个 web 服务器并且保存 web 请求上下文呢?
    2024
        39
    2024  
    OP
       72 天前
    @stabc 点了 start 再说,下班了
    stabc
        40
    stabc  
       72 天前
    @2024 其实你不必回答,我只是像引出一个结论,问题又回到了我一开始说的点上,你的 web 服务器实现方式还是和其他语言没区别,抛弃了 PHP 最具有优势的地方,那就是“无服务器”,或者说脚本化。
    2024
        41
    2024  
    OP
       72 天前
    @stabc 额,我手机给你回复的!无服务器是可以在 go 成开启端口,有请求来再解析脚本域代码,解析过程可以选择共享 vm 或者克隆隔离 vm ,就能做的全部代码是否持久化。go 和 php 是一体的,他们可以互相调用实现路由功能,如果你偏要认为实现不了就算啦
    stabc
        42
    stabc  
       72 天前
    @2024 为了性能面向 vm 编程哪来的“快速开发”呢?或者每次 REQUEST 都重新解析一边脚本里的函数,不是又回到了 PHP5 了么?
    2024
        43
    2024  
    OP
       72 天前
    @stabc 可选
    SethShi
        44
    SethShi  
       72 天前
    @2024 原生 PHP 在命令行就支持多线程,swoole 在 web 都支持协程了
    Steaven
        45
    Steaven  
       72 天前
    牛,有意思
    Gilfoyle26
        46
    Gilfoyle26  
       71 天前
    PHP:人生第二春
    2024
        47
    2024  
    OP
       69 天前
    @seth19960929 #44 尝试把 php 添加真的异步功能,一直有人尝试的,但官方没有打算,https://www.cnblogs.com/zx-admin/p/19002183
    https://externals.io/message/128053

    这些都是最近的讨论
    phithon
        48
    phithon  
       68 天前
    如果能完全实现 php 语法,并跑过官方测试,作为 php 解释器,其实真是有需求的,我以前一直在寻找类似的方案但没有找到。
    但如果不完全实现,只是一个“新语言”的话,感觉可能就不太可用了
    2024
        49
    2024  
    OP
       48 天前
    @phithon #48 新增工具导出 go 库,https://github.com/php-any/generator
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     852 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 19:32 PVG 03:32 LAX 12:32 JFK 15:32
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86