V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
2024
V2EX  ›  分享创造

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

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

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

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

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

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

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

    这些都是最近的讨论
    phithon
        48
    phithon  
       45 天前
    如果能完全实现 php 语法,并跑过官方测试,作为 php 解释器,其实真是有需求的,我以前一直在寻找类似的方案但没有找到。
    但如果不完全实现,只是一个“新语言”的话,感觉可能就不太可用了
    2024
        49
    2024  
    OP
       25 天前
    @phithon #48 新增工具导出 go 库,https://github.com/php-any/generator
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1420 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 16:49 · PVG 00:49 · LAX 09:49 · JFK 12:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.