混合 PHP 的崛起:将 PHP 与 Go 和 Rust 相结合

图0:混合 PHP 的崛起:将 PHP 与 Go 和 Rust 相结合

为了获得一些特定的优势,我们曾将应用程序开发成一个单一的 DDD 单体(我们称之为 “母体”),并在其周围添加几个较小的微服务(“子体”)。这些微服务大多使用Go构建,而核心单体服务则使用PHP 8.3开发。

这种堆栈在很长一段时间内为我们提供了良好的服务。Go 微服务可以高效地处理我们的高吞吐量请求,而精心设计的单体服务则让我们相对较小的后端团队能够快速、放心地交付功能。这是一个很好的平衡:在我们最需要的地方提高速度,在其他地方提高稳定性和生产力。

许多人可能都有过这样的经历,80% 的流量往往只针对 20% 的应用程序接口–这就是著名的Pareto 原则。不出所料,这 20% 的热点端点通常是性能最重要的端点。过去,我们的策略包括编写高度优化的代码、添加极端缓存层或将某些部分提取到基于 Go 的微服务中。这些方法虽然有效,但却增加了复杂性和运营开销。

元素周期表

但现在,得益于 PHP 生态系统中的新功能以及强大的库和运行时的兴起,将更多逻辑保留在单体中并同时实现卓越性能变得更加容易。让我们来看看几个令人兴奋的选择:

1. FFI(外来函数接口)

PHP 的FFI功能允许你直接从 PHP 调用C 代码。这就为系统级操作或性能关键逻辑打开了大门,而无需离开 PHP 项目。当然,你需要注意上下文切换的成本**,但对于合适的用例来说,它是一个改变游戏规则的工具。

2. 基于 Rust 的扩展

如果你不喜欢写原始的 C 语言,现在你可以用Rust(甚至Zig)编写 PHP 扩展。这样,您就可以将应用程序中对性能敏感的重载部分卸载到安全、内存效率高的编译代码中。尤其是 Rust,它在不牺牲速度的情况下提供了内存安全性保证,因此非常适合需要既可靠又快速的扩展。

3. 使用FrankenPHP进行基于Go的扩展

我们最近改用了FrankenPHP(在看到 PHP 基金会正式支持它之后)。在FrankenPHP的工作模式下运行PHP,速度之快令人印象深刻–在我们的基准测试中,有时比传统设置快**倍以上。

更令人兴奋的是,最近发布的版本引入了用 Go** 编写 PHP 扩展程序的功能。我们正在积极探索这一功能,因为它可以让我们用 Go 构建高性能的应用程序接口,并在 PHP 单体中无缝地公开它们。这样,我们就可以将 PHP 的生产力与 Go 的原始速度结合起来,而无需将所有东西都拆分成单独的服务。

但为什么不直接用 Go 或 Rust 重写一切呢?

这是一个公平的问题,我们也问过自己。我们不直接迁移整个后台的主要原因有两个:

  1. ** 重写成本高昂。** 许多应用程序已经非常庞大和稳定。重写风险大、耗时长,而且带来的问题往往多于解决的问题。在大多数情况下,重写应该是最后的选择。
  2. 对于大多数应用程序来说,PHP 能很好地完成工作。它速度够快,对开发人员友好,而且有一个庞大的生态系统提供支持。对于那些真正需要最高性能**的少数情况,你现在可以选择性地使用 Go 或 Rust 作为扩展编写部分内容–而不是重写整个系统。

简而言之,现代 PHP 生态系统为我们提供了两全其美的**:既能快速、自信地使用 PHP 构建系统,又能为性能关键部分提供强大的选择(C、Rust、Go)。这种混合方法让我们既能保持高效率,又不会在最重要的地方牺牲速度。

本文文字及图片出自 The Rise of Hybrid PHP: Blending PHP with Go and Rust

共有 150 条评论

  1. 我开始有点反感包罗万象的框架(如 Spring、Larvel、Phoenix 等),因为虽然使用它们构建新事物很有成效,但在使用它们构建的遗留项目中,我似乎总是遇到同样的问题。

    升级这些项目的依赖关系似乎总是个难题。这通常是因为(在构建过程中),人们无法完全按照 god 框架的 “规定 ”方式来做事,因为每个项目都必须应对特定的基础架构环境和/或业务环境,而这些环境和/或业务环境需要一些黑客攻击或额外的依赖性。然后,当你需要升级语言版本时,你就不能按照 god framework 的指南(如果有的话)去做了,因为这会破坏你的工作方法。因此,你最终会得到这样一个大杂烩,它永远不会更新,直到它达到一个临界点,无法继续在你的基础架构上运行,这就迫使你进行一个大型迁移项目。

    使用精选的库来构建网络服务的元素,并创建自己的高级抽象来使用它们,确实需要额外的时间投入,但它能让你更有控制力地进行逐个升级,并在需要时调整工作方式。

    我觉得围棋生态系统比大多数系统更遵循后一种方法,这让我一开始有点转变思想,但现在我越来越欣赏它了。

    • 对我来说,Web 框架是一种 “用完即弃 ”的东西。

      如果你制作的是一个简单的应用程序,那么网络框架会让你感觉非常神奇(就像最初的 “用 Rails 在 15 分钟内搭建一个博客 ”演示一样),但对于任何复杂的应用程序,我发现它们通常都会碍手碍脚。

      我个人越来越喜欢 “中级 ”HTTP 设置,比如使用 Node.js 的 Express 或使用 Java 的 Vert.x。

      [1]

    • 在 Python 的世界里,我认为这是微框架(Flask-esque)与宏框架(Django)的较量。我每次都会选择 Django。

      Flask 规定的太少,以至于每个项目都是雪花片。在 N 个可用选项中,你会选择哪个来处理 auth/templating/cookies/email/什么的。在尝试启用核心功能时,会产生真正的决策疲劳。更特别的是,这些库中有很多都是单个作者创建的,因此维护和安全性都很复杂。

      Django – 每个项目看起来都差不多。开箱即用的东西太多,如果必须使用库进行补充,就必须有特殊要求。由于许多代码都是第一方提供的,因此您可以更放心地对代码进行维护/检查是否存在安全问题。

    • Go 之所以没有一个宏大的框架,是因为该语言的类型系统发展严重不足,这使得构建复杂的、有意义地相互补充的库变得过于困难。为了能使用泛型,我等了九年才开始开发我的第一个 Go 数据库工具包。我成功了,但我无法摆脱的感觉是,我知道我在本科时使用 Java 会有更好的体验。如果能将结果类型映射/过滤/还原为另一种泛型类型,将彻底改变游戏规则。如果能指定联合类型,我就不再需要 “any ”类型了。如果能重载,就能清理大量代码。它需要在烤箱里多烤一会儿。

      • > Go 之所以没有一个宏大的框架,是因为该语言的类型系统开发严重不足。

        反驳: PHP。

        PHP 5.3 的类型系统能力更差,但却开发了几个可用的框架。

        • 这是个褒义词,不是反义词。我说的是 Go 的类型系统具有限制性。PHP 和许多其他语言允许将变量重新分配给任何类型,从而避免了这一陷阱。Java 和许多其他语言则朝着另一个方向发展,选择构建更完整的类型系统。

        • PHP 的类型系统是如此 “动态”,以至于很容易为其构建框架。

          例如,PHP 甚至允许像这样的函数调用:

          $language = “德语”;

          $functionName = $language.“_send_email”;

          $functionName(“Mike”, “mike_1@gmail.”, “Text…”);

          这种灵活性有其自身的问题,它之所以成为可能,只是因为 PHP 的类型系统非常宽松,但它在开发可重用框架时也非常强大。

        • PHP 已经完全回过头来,拥有了比 Go 甚至 JS 或 Python 更强大的类型系统。虽然花了很长时间,但它还是做到了,而且做得相当出色。

          过去,它之所以能做到这一点,是因为 PHP 的魔力。至少在过去,PHP 可以让你为所欲为。

      • 我认为 Java 的流 API 非常出色,我很喜欢。

        对我个人来说,没有 Hibernate 级别的 ORMs 并不是一个缺点,这只是因为我不喜欢 ORMs–让 chatgpt 为我吐出一些 SQL 和映射代码,并能随着时间的推移调整实际的 SQL 更可取(但这也只是我的偏好)。

        我不太同意 Go 的类型系统不够完善的说法,我认为它的局限性在其他方面提高了工作效率。在我使用过的各种语言中,我所扩展的 Go 程序第一次运行就能正常运行的几率最高,因为编译器和语言服务器 A)会对不匹配的用法给出有意义的提示;B)旧的 Go 项目能正常运行的几率很高,而我无需再担心如何用集成开发环境让它们正常运行。B)是他们对 Go 语言非常保守的结果。

        • 人们对 Go 的类型系统的看法不一致,是否可能是由于编写应用程序和编写库的经验不同造成的?我个人认为,在编写网络应用程序和 CLI 工具时,Go 代码中的一些重复是可以忍受的,但对于具有不同目的的库的可组合性来说,这确实是一个问题。回到数据库工具包的例子,查询生成器可以轻松返回结果类型,但如果我还想在查询前处理输入验证,然后返回 HTTP 响应呢?如果要在 Go 中端到端串联一个结果类型,就需要了解它可能映射到的所有不同类型/接口,我认为这对一个类型来说责任太大了,尽管所有这些功能都可以很自然地串联在一起并减少到一个错误。这些类型限制实际上迫使 Go 库生活在自己的孤岛上,无法相互组合。

          • 编写 Go 库的 “Go-ithic ”方式是对其 API 严格要求,并让消费者承担与之映射的工作。因此,如果我对你的示例理解正确的话(我可能理解得不正确),那么完全可以在验证器(validator)、查询生成器(query builder)和 http 响应(http response)之间进行映射,这对 Go 代码库来说是完全可以接受的,事实上也是更可取的。这样做更可取,因为我希望库有一个精简的应用程序接口,并专注于做好一件事,同时我也希望能清楚地知道我是如何与外部依赖关系进行映射的。

            另一种说法是,Go 的哲学不是抽象细节或试图隐藏细节,而是让程序的实际控制流尽可能简单明了。

            • 我知道这是围棋的哲学。比起教条主义,我更关心实用性。作为一个复杂库的作者,我很清楚类型系统会导致过多的胶水代码,而编写和维护胶水代码的成本很高。

              • 作为一个已经工作了几年的 Go 开发者,我并不这么认为。我发现编写胶水代码非常容易,因为它与其他胶水代码大体相同,而且我发现它易于维护,因为简单的控制流让查找 bug 变得容易。不过,也许我们在这里得到的启示是,因为 Go 当然是见仁见智的,它是一种适合某些人而不适合其他人的工作方式。这很好。

    • 没错,在我的领域里,只有 Go/Rust 是有用的。妄自菲薄的框架文化永远不符合要求。我认为 Rails/Laravel/Django 在处理关系数据库垃圾时非常有用。

    • > 升级这些项目的依赖关系似乎总是一个挑战。这通常是因为(在构建过程中)人们无法完全遵循神框架的 “规定 ”做事方式,因为每个项目都必须处理利基基础设施环境和/或业务环境,这些环境需要一些黑客或额外的依赖。然后,当你需要升级语言版本时,你就不能按照 god framework 的指南(如果有的话)去做了,因为这会破坏你的工作方法。因此,你最终会得到这样一个大杂烩,它永远不会更新,直到它达到一个临界点,无法继续在你的基础架构上运行,从而迫使你进行一个大型迁移项目。

      你能举一些具体的例子吗?

      我想看看其中哪些是开源的。以及它们是否有维护资金。

    • PSR 来了!在过去的大约 5 年中,我一直只使用与 PSR 兼容的组件,而不使用任何框架。无论是企业级项目还是小型服务,都是如此。原因都是一样的–那些包罗万象的框架从长远来看是行不通的。限制太多,维护/更新太麻烦。

    • 我已经离开网络开发工作好几年了,但我对框架的问题始终是 ORM。简单的 CRUD 应用程序总是运行得很好,但当我需要优化 SQL 查询或创建更复杂的东西时,我最终不得不在应用程序中添加黑客添加物,而这些添加物总是会破坏升级。

    • 我发现网络框架也是如此。你花在学习框架抽象上的时间可以用来挑选一个队列库或其他你需要的东西,然后把它添加到你的 Go 服务器上。

    • 对于 Laravel 而言,问题在于该框架默认情况下是以 “高效 ”为卖点的。在我看来,这个框架并没有真正的 “牛”。今天,它是更好了,但从历史上看,它只是symfony的一个包装,通过反射、可疑的serde、大量的魔法进行一些依赖注入,并对模板和路由进行了一些独特的处理,这可以说不是很好的处理?也许组件更好,但作为一种模板语言,blade 总体上似乎是落后的。

      有没有想过键入 `$model->foo 而不是 $model->getFoo()`,然后让 `$model->foo` 神奇地调用 `$model->getFooAttribute()`,但如果该方法不存在,又返回到 `$model->getAttribute(‘foo’)`?然后神奇地调用一些铸造方法,甚至可能从远程存储中获取无限的记录?这太工匠精神了,兄弟。如果你有五分钟时间,我可以告诉你更多。

      • 我一直不明白为什么要使用模板语言,因为 PHP 首先就是自己的模板语言。我也不理解开发人员现在做出的决定,有一天可能会被取代。这就像建造一座桥,却让 50 年后可能要拆掉这座桥的计划决定了所有的设计决策。

        事实上,这样做恰好能使代码更有条理、更可测试,但却掩盖了这样做的初衷所带来的浪费。它只是用可能需要也可能不需要的后端工作来换取额外的前端工作,其结果是在以后需要的时候让事情变得更简单。我并不是说这完全是件坏事,而是说它事实上也不是件好事。

        我想,就像所有事情一样,重要的是找到适合具体情况的平衡点。

        • PHP 中的模板语言在很大程度上是为了更好地符合人体工程学。当然,你可以有自己的辅助函数来完成 html 转义,或者有一个抽象层来将变量传递到 include 中,而不会污染全局变量的作用域,但这些都是模板。

          Twig 和 Blade 都是很好的模板引擎,它们都有自己的怪癖和特性,但在过去十多年中,它们也经过了实战检验,证明了自己的使用价值。如果有人想使用专门的模板语言来抽象 HTML 代码,我不会有太多怨言。

    • > 所以,你最终会发现这个大杂烩从未更新过,直到它到达一个临界点,无法继续在你的基础架构上运行,这就迫使你进行一个大的迁移项目。

      这与我的经历不谋而合,我花了几个月的时间才将一个较旧的 Spring 项目迁移到 CVE 和 Bug 较少的版本。在迁移过程中还产生了一些新的 bug 和问题,其中包括在 Windows 上编译产生的 .jar 可以正常运行,而在 Linux 上编译则改变了 Spring Bean 的初始化方式,导致它甚至无法启动(允许懒初始化的设置没有任何改变)。

      > 使用精选的库来构建网络服务的元素,并为使用它们创建自己的高级抽象,这确实需要额外的时间投入,但它让你可以更有控制力地进行逐个升级,并在需要时调整工作方式。

      是,也不是。如果你只负责布线,那当然可以。但这取决于开发人员需要编写多少代码(也取决于开发人员),如果您需要编写各种基本机制(如事务处理、计划任务、并行执行的任务池、键/值存储和缓存、验证、审计和度量、文件上传和下载等),那么您最终可能会得到一个定制的烂摊子。与 Spring Boot 相比,它的文档更少,你无法向任何人咨询如何解决其中的问题,有时它的架构既无法扩展,也无法正常工作,因为它不是经过几十年实战检验的东西。

      > 我感觉 Go 生态系统比大多数系统更遵循后一种方法,起初我的思维方式有些转变,但现在我越来越欣赏它了。

      我仍然同意这一点,对我来说,正确的做法确实是给你提供大部分你可能需要的技术工具,让你(或其他开发人员)只需编写一些胶水,将所有东西连接起来,根据你可能有的业务规则来安排数据如何在你的系统(资源、服务、验证器、存储库等)中移动。如果忽略了这一细节,事情就会变得很糟糕。

      在 Java 领域,我认为 Dropwizard 就是一个很好的例子:它使用了大量经过良好测试的惯用库,而不像 Spring(和 Spring Boot)那样死板,让您可以随心所欲地进行设置,同时也不会碍手碍脚:https://www.dropwizard.io/en/stable/getting-started.html

      在 Go 中,我非常喜欢标准库中已经存在的很多东西。

  2. > 简而言之,现代 PHP 生态系统为我们提供了两全其美的解决方案:既能快速、自信地在 PHP 中构建,又能为性能关键部分提供强大的选项(C、Rust、Go)。这种混合方法让我们既能保持工作效率,又不会在最重要的地方牺牲速度。

    对于重写不可行的大型代码库,我可以理解。

    但如果不是这种情况,根据我的经验,C# API 可以同时实现开发速度和执行速度。你很少需要使用 C++ 或 Rust。

    PHP 是一种很棒的语言,但它仍然不允许使用类型化数组之类的东西。例如,它可以接受日期数组中的字符串。

    • 我在 C# 世界和各种 Web/api 框架中浸淫了很长时间。

      如果深入研究,PHP 真的很不错,它包含了许多用于创建网页的优秀函数和内置功能。

      它也有一些问题,但在我有限的看法中,要快速地将一些东西组合在一起,PHP 是最好的选择。

      • 完全同意。我已经不怎么用 PHP 工作了,但要更快更方便地启动和运行一些东西,PHP 仍然是最好的选择。我把它用于网络服务和命令行脚本,当我只需要快速的东西时。

      • 举个例子,我的主要网站使用的是 C#,从开发角度和性能角度来看,我都很喜欢它。但我的个人服务器上也有 PHP,我会为一次性演示项目编写 PHP 脚本。我只需 ssh 进入我的服务器,vim projects/example.php/,它就会立即部署为我可以共享的链接。

        • 现在有了`dotnet run`. 你可以

          vim projects/example.cs

           var builder = WebApplication.CreateBuilder(args);
           var app = builder.Build();
              app.MapGet("/", () => "Hello World!");
              app.Run();
          

          dotnet run projects/example.cs

          我知道这与 PHP 不同,但对我来说已经足够接近了。

          • 我很高兴它能为你工作,但我想这并没有真正涵盖我所说的用例,因为我想有一堆这样的东西。举个例子,我做了一个快速网络钩子处理器,将一种服务的数据重新格式化,以适应另一种服务。我真的不需要为一个每周只会被访问一两次的端点启动一个全新的 VPS,所以这就是在我已有的服务器上做这件事的工作流程。

            PHP:

               - vim projects/webhook.php
            

            C#:

               - vim projects/webhook.cs
               - 指定端口号
               - 重新配置 Nginx/Caddy 为该端口号提供服务
               - 重新配置 systemd,使其在启动时运行 projects/webhook.cs
            
      • PHP 仍然存在的唯一原因是共享主机公司和 WordPress。

        PHP 最初的魅力在于你可以在服务器端编写脚本,“用 ?> 关闭 PHP”,然后吐出正常的 html,“用 <?php 重新开启 PHP”。

        对于初学者来说,PHP 简单、易懂,而且有_include_功能,这样你的设计就不会嵌套在乱七八糟的表格中。(但你的 CSS 绝对是垃圾)。

        如今,运行 JavaScript 已变得如此简单,我可以在一小时内创建一个基本的 jsx 网站,就像使用 PHP 和 includ 一样。有了 Bun,我还能快速编写数据访问层,并用 JWT auth(验证)连接起粗俗的 API。这两个都是周末项目。

        • PHP 可能名声不好,但老实说,我不认为 JavaScript 在现实世界中是更好的语言。

          我明白为什么 JS 对人们有吸引力,但从 PHP 转向 JS 感觉就像在互联网上赢得了一场争论–你可能会觉得这样做更聪明,但实际上,你所做的只是在一些不会让你变得更好的东西上浪费了时间。

          • Javascript 有坚实的基础。我不会做出这样的选择,但我理解这样的选择。布兰登-艾奇(Brendan Eich)知道自己在做什么,这一点很明显,事实上,如果它只是由捆绑线和绳子组成,它早就被取代了。

            另一方面,对于 PHP 来说,即使是在我开始编写 PHP3 的时候(所以肯定不是最开始的时候),它显然也只是把不相关的、一知半解的部分拼凑在一起,因此没有一个连贯的中心。

            • Eich 发明的 JavaScript 与现代 JavaScript 生态系统中的一团糟完全不同。现代的 node.js 代码也与 Eich 为 Mozilla 开发的 JavaScript 完全不同。

              同样,PHP3 与现代 PHP 也是天壤之别。

              你的观点有点像在说:“摩托车很容易维护,因为它们是基于一分钱的汽车”。时代已经变了,你的引用已经过时几十年了。

            • 我们需要在这里发布 JS 的怪事链接吗?在联署材料的基本内容中,几乎没有什么是合理的。坚实基础 "的想法对 JS 并不适用。对于 PHP 来说,它甚至可能更有效,而我是作为一个再也不想使用 PHP 的人说这番话的。

              • JS 在很大程度上是一种极简语言,只有少数几种选择。例如,数组是字段名为顺序编号整数的对象。

                最初的相等运算符是个错误,但十多年前已经通过 `===` 得到了纠正。没有一个合适的 int 类型是很糟糕的,它在很多方面阻碍了语言的发展,但除此之外,这门语言还是非常规范的。

                任何抱怨生态系统的人显然都没有尝试过 Python,经过十年的尝试,现在的 Python 几乎可以与十年前的 JS 相媲美!

                • 你不应该逆向比较。

                  说 “至少 x 没有 y 那么糟糕 ”并不能促进讨论,只会让人否认 x 的问题有多严重。

                  尤其是当我们一开始根本就没有讨论 y(在我们的例子中是 Python)的时候,更是如此。

          • 如果你不是从 PHP 转来的呢?如果选择的是坚持学习 Javascript 的全栈,还是在 Javascript 的基础上学习 PHP 呢?

          • 到 2025 年为止,JS 基本上只是一个比较目标。如果 PHP 开发人员使用像 Haxe 这样的东西,他们会惊讶地发现他们的程序是多么安全。但我通常只看到泔水。

        • 我不是 PHP 的忠实粉丝,但对于简单的网站来说,我认为你低估了它的强大功能和简单性。与 jsx 方法相比,它给人一种老旧的感觉,但老旧并不总是意味着糟糕。我越来越倾向于使用 PHP 首创的模板渲染模型,对于非完整应用程序的网站来说,它要简单得多,这意味着更快的迭代速度和更低的认知负荷。我认为你真的必须根据你所需要的复杂性来决定

          • > 我认为你必须根据你需要的复杂性来决定

            我不太同意。我认为目标应该是尽可能降低复杂性,但如果你不可避免地要把自己逼入绝境,那就不应该降低复杂性。

            如果你想要最简单、最可扩展的方式,那就编写静态页面,避免服务器端渲染。

            • 使用 PHP 怎么会比使用 JS 更把自己逼入绝境?如果使用 PHP,以后就可以直接服务/使用 JS。但如果使用 JS,以后就很难从 PHP 服务 HTML 了。除了这两种语言都有点把自己逼入绝境之外,我看不出使用 PHP 比使用 JS 更能把自己逼入绝境。

              • 问题是,如果我用的是 JS,那我到底为什么还要用 PHP 呢?我只需 await file(‘index.html’)return <IndexPage> 即可。

                认知负荷是空的。你只是很难把你学到的行为拆分开来。返回 jsx 的一个组件与编写 PHP 的 include 是一样的。

                • 那么,如果返回组件是一样的,一个(PHP)怎么会比另一个(JS)更把自己逼入绝境呢?

              • 我是从现实世界的业务角度出发的,而不是业余爱好项目。

                你不可避免地需要将网页托管到 CDN 等其他地方以降低延迟、与其他后端集成,而最大的问题是让前端开发人员能够完全控制 HTML,这样样式表和 javascript 就不会因为他们无法控制的原因而随机中断。他们应能在本地使用模拟而不是服务器开发所有内容,并使用他们想要的任何构建工具和框架。页面结构还涉及搜索引擎优化和可访问性问题。这些都不应该由后台开发人员来决定。有时,客户可能希望快速完成简单但非常具体的页面修改。这些过程中的任何一个环节都不应该依赖于后端团队,因为他们将不得不重构多年未动过的垃圾代码,而这些后端团队对此并不关心,而且会拖后腿。

                摆脱依赖性并在代码中建立与开发团队组织方式一致的良好边界总是件好事。我不知道为什么有人会选择 SSR,除非他们很久没有做过网络开发了,或者正在开发一个遗留项目。即使一开始这只是一个业余爱好项目,你也需要为未来的维护者保持整洁。

                • 除了 SSR 部分,我都同意。SSR 回来了,就像回到了 1996 年。不过,这不是老式的使用标签类路径(tag classpath hell)为 jsp 页面提供服务的单体,而是为了更快地渲染而从服务器端提供的客户端页面。我们现在又多了一层。

                  浏览器 -> 客户端服务器页面 -> 业务逻辑 API -> 后台系统。

                • 我认为,假设后端开发人员不关心这个或那个,或者他们 “拖后腿 ”是很想当然的。

                  在我看来,你描述的那些人就像是代码猴子,他们对后台工程的决策毫无反驳意见,只要市场营销人员一抛出任何东西,他们就会立即行动。我们已经有太多这样的人了,他们让网络变成了一个乌托邦式的世界。

                  让我告诉你,我主要做的是后端工作,因为前端世界的所有炒作都令人反感,但我做前端工作时,我不会做半途而废的事情。我做的网站比 95% 的 “响应式 ”网站响应更快,而这些网站大多是由前端开发人员开发的,这也不足为奇。这是因为我不盲目跟风,而是通过网络标准和 CSS 来解决响应性问题。

                  就在前几天,我增强了正在构建的平台中的几个页面,使它们在轮询后台 API 时可以完全不使用 JS。没有什么太复杂的,只是在后台采取了一些预防措施,使这些页面能够被重新加载并呈现更新状态,同时避免重新加载时在后台触发新的不必要的重复操作。我很少看到前台会花这么大的力气来使网站更易于访问和保护隐私。那些优秀的网络开发人员都去哪儿了?

                  在我看来,一个优秀的开发人员只要掌握了网站开发的基础知识,最重要的是 HTML 和 CSS,其次才是 JS,就能比我们今天在网上看到的大多数网站做得更好。目前的主流显然并不尽如人意。

                  为什么要使用 SSR?因为它不需要用户运行不受信任的 JS。因为它不需要每个客户端重复渲染相同的内容。因为它对客户端的要求更低。因为它通常需要传输的数据更少,因为没有前端框架需要发送代码。因为它不需要在破坏浏览器功能后对其进行修复。选择 SSR 的理由有很多。此外,我还想说的是,你可以在使用 SSR 的同时,将渲染页面的逻辑与其他代码分开,这样 SSR 就只能访问 API 路由。这样,其他人就可以为该 API 构建替代前端。

        • PHP 的类型系统比 JS 更强大,而且总体上更符合人体工程学。

          Typescript 是存在的,但如果我要编译一些东西,我会使用真正的语言或框架,比如 dotnet。当我可以直接安装 dotnet 时,我没有理由使用 typescript 和 node 并安装 100 个软件包。

          • 安装 dotnet,然后为 .net core、asp.net、identity、ef 等安装 100 个软件包。别自欺欺人了。

            虽然强类型语言很好,但我还是喜欢能用它来处理事情。我喜欢能完成事情。这就是我不再使用 C++ 的原因。这也是我不再使用 dotnet 的原因。类型系统、正确性、微软的方式、缺乏支持或揠苗助长之类的废话太多了。当他们扼杀 XNA 时,我就失去了他们。

            Typescript 其实不错,除了它是 JavaScript 的转译器这一事实。这部分糟透了。

            我想要一个 C++,有类型,有内存安全,有垃圾回收,有指针,有像 dotnet 一样的开发体验,但我们没有这些东西。

            • dotnet 是一个包含电池的框架… 它比任何其他语言(包括 JS 和 PHP)都包含得多。

              > I want a C++, with Types, with memory safety, with garbage collection, with pointers, with a dev experience like dotnet, but we don't have those things.

              Dotnet,你想要 dotnet。Dotnet 拥有所有这些。是的,它有指针。

        • > PHP 仍然存在的唯一原因就是共享主机公司和 WordPress。

          不幸的是,对于这些无稽之谈,我实在想不出什么有建设性的意见。

          > 今天,运行 JavaScript 变得如此简单,我可以在一小时内创建一个基本的 jsx 网站,就像使用 PHP 和 include 一样。

          你是在假定人们都认为使用 JavaScript 工作更为可取。

          • 很遗憾,这是事实。从 PHP 网站来看,95% 都是 wordpress/drupal/<cmstool>。

          • Meta 之外仍然没有人关心 hack。

            我认为 PHP 当年的优势已经被 Python 所取代。

            也许它现在更好用了,但在经历了 25 年的职业生涯后,我已经不再怀念它了。

            • 我不知道你提到 Hack 想表达什么意思。

              在这一点上,它与 PHP 已经背道而驰,基本上是另一种语言,(我记得)实际上比 PHP 8 还要慢,而且 HHVM 甚至不再支持 PHP 了。

              因此,Meta 之外很少有人关注 PHP 也就不足为奇了。

              我也在几年前放弃了 PHP,而且并不怀念它。但这并不意味着我不承认选择 PHP 仍有完全合理的理由。

              • 是的。

                元/黑客(meta/hack)可能是 PHP 的另一大支柱,而不是你回复的那个人所说的那样。而使用 HHVM 的 hack 本应是 PHP 的灵丹妙药。

                我只是说说而已。

                人们以前用 PHP 来完成的任务,在很大程度上已经被 Python 取代了。

            • > And still nobody outside of Meta cares about hack.

              因为大家对 PHP 都没意见。我甚至没有直接使用它,但大部分网络都是在它的基础上运行的。

    • >例如,它很乐意接受日期数组中的字符串。

      是的,时不时会有一些奇怪的东西出现。

      最近我遇到了一个奇怪的 JSON 去序列化错误,着实让我困惑了好一阵子。我通常使用 json/_decode(),并将第二个参数设置为 true,这样就会得到一个关联数组。但这并不能说明问题的全部。如果在解码时关键字是数字,PHP 会把它的关键字变成 int!而不是像其他的那样变成字符串。我猜它做了等同于 is_numeric() 的检查或其他什么。

      这样就产生了一个数组,其中的键可能是 int,也可能是字符串 :/ /。

      尽管它有很多缺点,但它仍然是一门神奇的科学怪人语言!

    • > 例如,它很乐意接受日期数组中的字符串。

      虽然完全正确,但你使用的是静态分析器,它不会让你这样做。

      泛型支持很可能会在不久的将来出现,它的发展势头已经很猛了: https://thephp.foundation/blog/2025/08/05/compile-generics/

      • 我从事 PHP 工作已经有 15 年了,其中有 10 年我都得到了支持泛型的承诺。为了您的健康,请不要屏住呼吸。

    • 事实上,你仍然不需要重写。使用 Worker(swoole、frankenphp……)运行 php 可能和 node 一样快。对于类型化数组,php 有像 phpstan 这样的静态分析器。

    • 自从微软停用 VB6 后,我再也不会使用微软语言了。开源语言是唯一明智的选择。

      • 你也不使用 Typescript,因为它是微软语言?另外,.NET 已经开源十多年了,而 c# 从一开始就是免费开放的(Mono 实现)。

      • C# 是开源的。

  3. 加入 {{company}} 时,一切都还在使用 5.4,那时对 PHP 非常反感。

    但随着 PHP 发布了更多新版本,我相信我们从 PHP 迁移到其他语言(这才刚刚完成)可能是一种倒退(that PHP is awesome)。

    每个人都还以为 PHP 和 5.x 时代一样,其实不然。

    • 我不太确定:如果你考虑到招聘人才,那么在更广泛的行业中,人们对 PHP 的看法(不管是对是错,我们不要在这里争论这个问题)会阻碍很多优秀开发人员的加入。因此,即使在技术上不再有必要,但在雇主品牌建设方面,我认为摒弃 PHP 是有帮助的。

      • 说得没错,15 年前我写过很多 PHP 代码,我发誓再也不干了。现在我是一个更好的开发者,2025 年我会主动避开任何做 PHP 的公司。

        • PHP 是一种与 15 年前截然不同的语言,大型应用程序与 Java 或 dotnet 几乎没有区别。在这一点上,PHP 的类型系统比 JS 甚至 Python 更有内聚力。

          • 但我为什么要使用它呢?这门语言太烂了,我想现在有了足够的抽象来掩盖它,但它们也只能做到这么多。你还是要写 $variables 并调用 array_* 方法等等。我宁愿使用那些没有这些遗留问题的语言。我也避免使用 Perl。

            • 每种语言都有遗留的垃圾,至少所有重要的语言都有。

    • > 现在 PHP 棒极了。

      它肯定_更好_,但很棒?这也太夸张了吧。

    • 我越来越喜欢 PHP 了。我得去看看,谢谢你的建议!

    • 4 年前我们也遇到过同样的情况,我们选择了继续使用 php,并选择了第 8 版。

  4. Pasir 类似于 Frankenphp,但使用的是 Rust 语言。非常有前途,但仍处于开发初期:

    https://github.com/el7cosmos/pasir

    它使用以下针对 Rust 的 Zend API 绑定:

    https://github.com/davidcole1340/ext-php-rs

    还有各种有趣的实验,比如 ngx-php,它基本上是通过 Zend API 将 PHP 嵌入到 nginx 二进制文件中:https://github.com/rryqszq4/ngx-php

    还有 workerman,它有一个 ASIO 库的混合后端,因此可以获得相当快的运行速度: https://github.com/walkor/workerman

    • 这些软件是否支持现有的 PHP 模块?

    • 感谢您的建议。看起来很酷,但正如您所说,离生产准备就绪还很远。我们选择了 frankenphp,因为我们看到它得到了 php 基金会的支持。

  5. 调试和维护的复杂性似乎被忽视了,如果可以,请不要这样做。

    • 我们刚刚选择了 frankenphp,但我不知道它是否会使调试变得更糟糕。

      • 处理 3 个相交的堆栈比处理单个堆栈更复杂。Go 工具链包含电池,而且连贯一致。作者承认没有使用它是因为传统(和偏好)。

        • 我知道在任何语言中编写扩展都会增加一些复杂性,但我相信如果扩展选择得当,它们在某种程度上是一劳永逸的。例如,在 Go 中创建 pdf 文件会比在 php 中创建更快。

  6. 我一咬牙把我的应用程序从 PHP 重写成了 Go,这给我的公司带来了回报,我们谈论的是 20K 行 PHP 代码,减少到了 4K 行 Go 代码,而且还提高了效率。

    我认为有些公司只需要跳一跳,计划重写,添加测试(使用 Go 更容易),如果他们是一家 PHP 商店,我认为这样做是值得的。

    而不是将 Rust/PHP 或 Go 混合在一起,形成一个无法维护的混乱代码库。

    • 从 PHP 到 Go,你是如何减少 LoC 的?

      Go 是一种相当冗长的语言,而对我来说,PHP 在冗长程度上处于中间位置(Haskell 会偏简洁,Java 和 Go 则偏冗长,特别是由于每次函数调用后都要不断进行错误检查)。

      • 也许他们指的是依赖关系?现在有一些臃肿的库,但因为 PHP 是一种动态语言,所以只有当它在你的热路径中时,臃肿才会变得重要。

        但我觉得一个 2 万行的 PHP 应用程序已经很小了……我们的应用程序中可能有 20 个不同的 1 千多文件。这些文件并不漂亮,但速度够快,而且能正常运行,所以我不会为了好玩而重写它们。

        话虽如此,在处理这个遗留的庞然大物时,我们经常会找到删除几百行的方法,因为有很多旧功能已经不再为业务所需要,这样我们就可以从代码库中删除这些认知负荷。也许我们也有过类似的经历,重写只是一个很好的时机,让业务部门承认这些功能不再重要。我们运营的是一个电子商务网站,因此应用程序中充斥着大量的营销小实验,我们需要不断地删除旧的实验,添加新的实验,让人们用功能标志进行调整和测试。删除死代码只是工作的一部分。

    • 我不明白你是如何从 php 到 go 中获得 5 倍的低 loc 值的。

      php 并不完美,但它有很多 go 所没有的快捷语法。

    • 但问题始终是:重写是提高效率的原因,还是新语言的原因?

      • 两者都是。

        Go 让这一切变得值得,而且也很容易交给另一位经验丰富的开发人员。

        • 很好,你在 Go 中发现了哪些 PHP 中没有的东西?你怀念 PHP 中的任何东西吗?

    • 我很惊讶你把它写得更紧凑,而不是变成 40k 行的 if err!

      我曾在 Python 中重写过一些东西,它变得非常冗长,另外还有用于测试的依赖注入模式。

      • PHP 中的大量内容主要是模板 + 数据库调用,适用于许多网站。

        例如,如果你将 Go + Templ 结合起来,你的 “if err ”大部分都是关于数据库调用的。无论如何,这都是 PHP 中需要检查的内容。

        是的,在进行类型转换等操作时,if err != nil 会让人非常沮丧。但如果你已经在数据库调用中通过反射实现了这一点(在结构体中转换为正确的类型),那就会节省很多。

        获取外部数据时也是如此,直接将其转换为结构体,如果出错,只需一个 “if err”。

        如果你只是在 Go 中进行 PHP 风格的编程,那么,_,像 PHP 一样忽略错误,你可以惊慌/恢复,使 Go 的行为和 PHP 一样糟糕,以节省 “if err”。)

    • 我无论如何都不推荐重写(以前曾成功重写过 2 次,但我还是没有选择重写),而且新php的运行时间可能会非常快。

  7. 有时候,我觉得我们应该回归基本:像素、数据、延迟/带宽。网络是一个优化问题,因为我们希望在延迟和带宽限制条件下,以感知速度呈现正确的像素。

    它应该更像是:用户即将看到哪些像素?设置像素需要哪些数据?下一步可能需要哪些数据,并以最佳方式预取–类似于这样。

    • https://github.com/timschmidt/alumina-ui,我一直在使用 egui 工具包为 WASM 构建系统,该工具包只接受一个与浏览器大小相当的 HTML 画布,然后开始对着它大喊 WebGL。

      我可以忘记 HTML、Javascript、CSS 以及浏览器和网络的大部分复杂功能,只需用我最喜欢的语言编写一个应用程序,它就能快速运行,并为用户提供 GL 加速图形。

      我对 WASM / WebGL 感到非常满意,因为它是实现这一目标的抽象概念。

      • 我一直在想,网络发展到这一步需要多长时间。画布一出现,这似乎就不可避免了。从技术上讲,你甚至不需要用 gl 或 wasm 来重写整个 js 渲染引擎,只需在全尺寸画布上喷射像素即可。

        你用它创建了一个真正的桌面风格的 gl 应用,这很酷。

        • 我期待着有一天,Javascript 能成为另一个 WASM 填充程序,通过定义明确、便携、快速的 DOM API 加载到页面中。我也迫不及待地希望更多地方采用 WebGPU。现在我只能依赖 WebGL2,因为 WebGPU 默认情况下在 Firefox/Linux 稳定版中不可用。

          另一个小麻烦是,“cargo bloat ”和类似工具还没有用于wasm的后端,因此我需要修复原生构建,以便利用这种分析,这也是我所希望的,因为我从微控制器闪存中提供整个应用程序,而我只有4-16MB来存储应用程序和固件,包括 http 服务器和网络协议栈。

          • 我不想。我不希望网络成为不透明二进制应用的运行时。现在,我们仍然保持着用户对 DOM 和应用程序的某种控制;当一切都变成 WASM 和 WebGPU 使用自己的自定义渲染器时,人们随意检查、修改、黑客攻击、修补和调整的能力将完全丧失。

            我是通过观察网页并了解其工作原理才学会如何为网络构建的。你所描述的是从分立元件的电路板到在一团环氧树脂下的单个微小集成电路的转变。

            • 我认为这是一个或多或少具有普遍性的优化过程。如果重要的东西能够保持足够长的时间,那么所有重要的东西最终都会被硅片所取代。这其中有几个阶段。

              和你一样,我也对 SGML 和语义网怀有深深的眷恋,在 Alumina 合理的地方,我正在使用 RESTish API。

              但我并不喜欢 Javascript 语言或框架。20 年已经足够了。而且我也不相信,我从 CDN 上下载的一些 4MB 的减缩混淆 Javascript 会比类似大小的 WASM 二进制文件更容易访问。至少,WASM 表示法有先进的工具。想让你读懂他们代码的人仍然会让你轻松读懂,而不想让你读懂的人则不会。

              关于学习,WASM 在浏览器中提供了一些令人难以置信的系统,如 https://lovr.org/,这是我小时候最想拥有的,但它也不是 javascript。这与图灵完备性有一定关系,一旦你让一个小软件进入你的结构化文档,它就会全部进入。又或者是 “给老鼠一块饼干”?

              我理解你所说的可发现性。但我这个开发人员非常喜欢有一个相对简单的二进制解释器,作为网络交付的跨平台二进制应用程序的目标。我的希望是,为想要开发应用程序的人(包括我自己)提供这样一个多汁的目标,让他们摆脱语义文档功能的束缚,让两套代码都变得更简单、更专注。因为我认为,这是人们使用网络的两项不同的任务,两者都是完全正确的。

            • 如果你看看一个典型的 next.js 类型的应用,它包含了所有的构建步骤、最小化、后 css、树状抖动、客户端/服务器端等,它并没有完全针对逆向工程进行优化。也许这艘船已经扬帆起航了。

      • 这个 我喜欢

        • 谢谢。要让它控制第一台机器,还有很多工作要做。我目前正在考虑如何为我希望支持的所有微控制器和电路板组合进行最佳构建,然后将运动控制连接到用户界面。我刚刚完成了 csgrs 的节点图界面,还有很多工作要做。进展缓慢

          请考虑加入 Discord: https://discord.com/invite/cCHRjpkPhQ

          目前只有我一个人在里面。带朋友一起来吧!笑

    • 用户看到的像素只是图片的一部分。与所有软件项目一样,你不仅要优化即时用户体验,还要优化开发时间。第一次绘制的时间很少与开发时间一致。

      • 处理过度获取/获取不足的问题肯定会耗费开发时间。创建只供网络用户界面使用的无穷无尽的 api 端点也非常耗时(业界终于认识到这是多么愚蠢的做法,并重新采用较早的 SSR 方法)。不如这样,“允许用户访问服务器上的这些信息–系统由您来确定何时何地获取这些信息的一部分以供查看”?

      • 我不在乎像素,我想看的是结构化的文档。至于如何查看,那是我的事。

        • 明白了,你不在乎香肠是怎么做出来的。这完全没问题。

          • 这听起来不像是红墙(redwall/_hp)的意思;听起来他们的意思是像素是错误的抽象层次。如果是这样,我同意:网络是关于标注文本的。当你把它分解到最基本的东西时,你得到的是电传打字机,而不是光栅。

            • 我觉得这更像是终端而不是浏览器。无论如何,我的真正意思是像素需要一些数据(或任何你想要的抽象概念)。除了当前视口和下一步可能需要的数据外,你不需要其他任何数据。不能少,也不能多。不会过多或过少获取数据。我觉得这样会更好。

  8. 我很好奇,这里讨论的是什么样的工作负载,需要使用 C、Rust 或 Go 扩展?我当然相信它们是存在的,但我真的很想了解更多,以及为什么要将这种复杂性添加到堆栈中而不是通过其他方式来解决。

  9. 我不喜欢 PHP 的一点是,整个应用程序在每个 http 请求中都要进行引导(自动加载并重新评估配置)。当然会有缓存之类的东西,但感觉就是不对劲儿(比如,与用 golang 写的 http 服务器相比)

  10. 很高兴看到 PHP 还在继续。

  11. FrankenPHP 听起来很有前途,但实际上它是个怪胎:没有模块就没有人使用 PHP。FrankenPHP 支持的 PHP 模块列表在哪里?有可能用一些额外的 PHP 模块编译它吗?如何编译?我看到它与 Caddy 绑得很紧。我对该网络服务器不太熟悉,我更喜欢nginx,但没有任何指南提到是否可以在FrankenPHP中使用nginx(作为php-fpm的替代)。另外,无论是 Caddy 本身,还是 FrankenPHP 的 docker 镜像,在使用 let's encrypt 证书方面都很有意见,而且如何通过 HTTP(如果外部提供 SSL)或使用自己的证书使其工作也不是一件小事。

    • > FrankenPHP 听起来很有前途,但实际上它是个怪胎:没有人会在没有模块的情况下使用 PHP。

      你通常会在 Dockerfile 中自行构建模块,例如 "psql "模块:

      RUN apt-get update && apt-get install -y libpq-dev && docker-php-ext-install pdoo_pgsql && apt-get remove -y libpq-dev && rm -rf /var/lib/apt/lists/*

      
      对于 http,只需在 Caddyfile 中输入以下内容即可:
      
      http://:80 {
              # 其余的 Caddyfile 指令
       }
      
    • 静态编译时,默认使用这些模块:

      amqp,apcu,ast,bcmath,brotli,bz2,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,ftp,gd,gmp,gettext,iconv,igbinary,imagick,intl,ldap,lz4,mbregex,mbstring,memcache,memcached,mysqli,mysqlnd,opcache,openssl,password-argon2,parallel,pcntl,pdo、 pdo_mysql,pdo_pgsql,pdo_sqlite,pdo_sqlsrv,pgsql,phar,posix,protobuf,readline,redis,session,shmop,simplexml,soap、 sockets,sodium,sqlite3,ssh2,sysvmsg,sysvsem,sysvshm,tidy,tokenizer,xlswriter,xml,xmlreader,xmlwriter,xz,zip,zlib,yaml,zstd

      https://github.com/php/frankenphp/blob/main/build-static.sh#

  12. 当我做这样的事情时,我只是用新的/快速语言编写前端应用程序,然后将不是用快速语言编写的内容转发给传统应用程序。你甚至可以在新应用中为前往旧应用的请求添加中间件、缓存或度量,因为你可以在请求和响应周围运行(快速)代码。

    这是两全其美的办法–新应用可以看到所有流量,但不需要实现 100% 的路由。添加到新应用程序中的任何内容都可以优先于旧应用程序,分割出反向代理的路径空间。

    为此进行 FFI 似乎过于复杂;我宁愿接受向不同进程提出另一个请求所带来的微小性能损失。

    • 好主意,你选择了哪种语言?使用 frankenphp,你可以直接编写所需的 apis,使其成为真正快速的 go 扩展。

      • 当然是 Go。

        • 我们用 Go 编写了网关,它还可以处理身份验证,然后将用户数据传递给其他服务(Go 和 php)并返回其响应。

  13. 事实证明,dlopen 正是我们一直需要的 "微服务 "架构。

  14. 其中一个与另一个不同。Go 也是垃圾回收语言。把一种垃圾回收语言嵌入另一种语言,就意味着有两个垃圾回收器在互相对抗。

  15. 我曾尝试用 Ruby 和 Rust 提出这个建议。我们有一个超级老旧的 Rails monolith,只想对几个端点进行超级优化。只需让 Rust 对单体 “下点毒”,就能非常容易地逐步适应。而且你还能保持单体带来的大量生产力收益。但人们似乎更喜欢完整的网络边界和独立的服务。

  16. 还有 RoadRunner,一个更像 PHP 的 FrankenPHP 替代品:

    https://roadrunner.dev/

  17. 我的事业成功在很大程度上要归功于当年学习 PHP。但最近我又开始学习 PHP,因为我必须做一些维护工作,而软件包管理的经验真的非常非常糟糕。

    我真的觉得有很大的机会让某人为 PHP 创建一个 astral.sh。

    如果有一个合适的软件包管理器,PHP 能做的事情会比现在多得多。

  18. PHP 的 FFI 支持是一个已经存在了 2/3 的功能,而且没有得到改进。这让我怀念 Python 的 cffi。

    • 不过我打赌你不会怀念 Python 比 PHP 差劲的性能!不。我用这两种语言处理不同的事情(祝你好运,能用 PHP 检测到 ai 的东西!),但事实上,我不得不使用 Python 的 C 语言扩展,才能以合理的速度运行一个基本的循环,这对我来说仍然很奇特/可怕。

  19. 这让我想起了雅虎当年的工作方式。他们所有的显示逻辑都在 PHP 中运行,而复杂的业务逻辑则在 c 扩展中运行。

    • 如果您对雅虎有更多了解,我很乐意听听他们为业务逻辑开发了哪些扩展。

  20. 这么多年过去了,我们还在假装 PHP 是一种几乎可以解决所有问题的有效解决方案,这简直是个笑话。

    不仅如此,现在我们还有这些 “科学怪人 ”的解决方案,在 PHP 的基础上解决了所有的互操作问题。

    由此可见,人类真的是学不会。

    • 我并没有建议所有类型的项目都使用 php,我自己也没有这样做。我刚刚提到的是,如果你为了更快地响应某些应用程序而选择其他方法,那么你仍然可以继续使用 php。

    • 现在的 PHP 与 Ruby 或 Python 并没有什么不同。但是,考虑到 NodeJS 和 Rust 等新的更好的选择,我认为这三种语言都不是有效的解决方案。

      • NodeJS 比 PHP 8 落后了 10 步。类型系统更差、安全性更低、软件包生态系统一团糟、速度更慢…… 诸如此类,不胜枚举。

        我们可以通过使用 typescript 或其他方法来 “掩盖 ”其中的很多问题,但现在我们编译 JS,输出速度却并不快。这时,请使用 C# 或 Rust 这样的编译语言。

        • 作为一个不喜欢 npm/ts 的人,我必须说我觉得这几乎是痴心妄想。

          TS 比 PHP 好得多,而 node 也快得多。

          • TS 的类型系统与 PHP 几乎完全相同–结构类型、联合类型等。我不知道为什么人们认为 PHP 是无类型的–它已经不是 5.4 了。类型系统功能非常齐全。

            区别在于 TS 需要编译,而 PHP 不需要。如果必须编译,我们还不如使用 C# 这样更安全的语言。

            另外,Node 并不快。我不知道为什么人们会认为 Node/JS 快。JS 的性能特性非常差,而且无法修复,因为这是语言设计的一个因素,不过 PHP 也有类似的问题。

            Chromium 针对特定场景进行了优化。它仍然是一种动态类型、垃圾收集的语言–在play pretend medium blog中优化一个for循环并不能改变这一点。

            • > 不,Node 并不快。我不知道为什么人们会认为 Node/JS 很快。

              Node 并不快。它比 PHP 快,这一点非常明显。

              最粗略的搜索和实践经验都会告诉你这一点。

              • 我不认为 Node 比 PHP 快,因为你可以非常积极地优化 PHP。在 opcache 缓存、热解释器、JIT、frankenphp 之间…

                Chromium 当然会优化 JS,但不是针对这种用例。它针对前端进行了优化。我相信其中很大一部分原因在于编译速度有多快,这意味着更少的激进优化。我敢肯定,chromium 绝对不会针对长寿命的 JS 进程进行优化。

                不过,公平地说,我并不知道哪个更快。根据我自己的经验,在生产中,JS 的速度慢得惊人,而 PHP 则很快。但这可能是 React 影响了我的看法。

                总而言之,JS 和 PHP 非常相似。让 JS 变慢的东西和让 PHP 变慢的东西是一样的。这并不像 JS 有什么神奇的魔力,能把解释型动态类型语言变成高性能语言。

      • 是的,我经常使用 php colab 在 gpus 上运行 numpy,这是我在大学的 php 数据科学课上学到的。

        现在它们基本上是等价的。

        • 你是对的,Python 有一个方面比 PHP 更有优势,但这与语言本身无关,更多的是与人们为了其他目的而改造语言的工具有关。因此,这有点像说 Python 和 Ruby 完全不同,因为 Rails 是为其中一种而不是另一种而存在的。

        • >我是在大学的php数据科学课上了解到的。

          I rest my case…

  21. 我用 Perl 做这个。

    我喜欢 Perl 的原因之一是它对向后兼容性的高度承诺。

    我喜欢 PHP 是因为它可以很容易地为我的应用程序进行安装,但它的破坏性改动在过去让我吃了不少苦头,所以我尽量少用它。

    这两者结合在一起,是个不错的组合。

  22. 这听起来绝对是令人厌恶的维护。你们到哪里去雇那些愿意为这种垃圾工作的开发人员呢?

    • 正如我所提到的,我们选择了由 php 基金会官方支持的 frankenphp。此外,我们的代码库中只有不到 5% 是 Go 语言。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注


京ICP备12002735号