2012 年有一篇很火的博客:PHP: a fractal of bad design。作者在文中对 PHP 大张挞伐,几乎就差说这是反人类的设计了。第一次读到此文时,我正在一个恶心的地方处理很多遗留的 PHP 项目。读完文章时,我开始思考是否要辞职去做一些与编程完全不同的事情。
幸运的是,此后不久我就换了工作,而且 PHP 从 5.* 开始也成长了很多。今天,我想对那些不再使用 PHP 编程,或者被遗留项目困扰的人说点什么。
Spoiler:PHP 跟其他编程语言一样,都有点自己的小毛病。很多核心函数的方法签名不一致,配置设置仍然不清不楚,仍然有很多开发人员在写蹩脚的代码——因为他们必须这样做,或者说,他们没有更好的方法。
但今天,我想说的是 PHP 好的一面:看看 PHP 的成长,共同探讨一下如何编写干净且可维护的 PHP 代码。希望大家可以暂时把偏见放进肚子里,哪怕只有几分钟。等我说完,你可以把它们再拿出来,但是你一定会惊讶于过去几年里 PHP 的成长。
快速阅读
PHP 每年都在积极开发新版本
自 PHP 5 时代以来,性能至少翻了一番,甚至有可能是曾经的三倍
有极其活跃的框架、包和平台生态系统
过去几年增加了很多新特性,语言也在不断发展中
像静态分析器这样的工具已经成熟,并且会越来越多
更新:有人让我展示一些代码示例,这当然可以!下面有两个例子:一个是我比较喜欢的项目,是用 PHP 和 Laravel 语言编写的;还有一个是我们办公室维护的几百个 OSS 包的列表。代码地址如下:
https://github.com/brendt/aggregate.stitcher.io
https://spatie.be/opensource/packages
那我们开始吧。
历史背景
首先,我们快速回顾一下 PHP 的发布周期。现在的 PHP 版本是 7.3,预计 2019 年底将发布 7.4,然后下个版本将是 PHP 8.0。
自 5.* 时代之后,其核心团队努力保持着一年一版本的发布周期,并在过去四年中成功做到了这一点。
一般来说,每一个新版本都有两年的有效支持期,然后再用一年来做「安全修复」。这么做的目的是鼓励 PHP 开发人员尽可能使用最新版本,因为每年的小升级比从 5.4 跳到 7.0 版本要容易得多。
PHP 的版本时间表如下:
其中,PHP 5.6 是 5.*时代的最新版本,它的下一个版本就是 7.0。如果您想知道 PHP 6 发生了什么,可以收听 PHP 圆桌播客 :
https://www.phproundtable.com/episode/what-happened-to-php-6
了解这些之后,我们可以进一步探讨关于 PHP 的常见误解了。
PHP 性能
5.* 时代的 PHP 性能充其量也不过是平均水平,但是在 7.0 中,PHP 核心的大部分内容都被完全重写,性能也因此提高了两到三倍。
光说不练假把式,我们用基准测试结果说话。有人对 PHP 的性能进行过基准测试,这些测试被很好地记录在了 Kinsta 上:
https://kinsta.com/blog/php-benchmarks/
自从 7.0 出现以后,PHP 的性能一直处于上升期。PHP web 应用的性能与其他语言的 web 框架相当 (在某些情况下甚至更好)。不信可以看看这个通用基准测试包:
https://github.com/thebenchmarker/webframeworks
PHP 框架虽然没办法做到比 C 和 Rust 更好,但是它比 Rails 或 Django 要好得多,并且可以与 ExpressJS 相媲美。
框架和生态系统
说到框架,PHP 已经不再只是 WordPress 了。作为一名专业的 PHP 开发人员,我想说的是:WordPress 根本不能代表现在的生态系统。
一般有两个主要的 web 应用程序框架和一些小框架,比如 Symfony 和 Laravel。当然,还有 Zend、Yii、Cake、Code Igniter 等,但是只有这两种主要的框架才能代表如今的 PHP。
这两个框架都有一个包含大量包和产品的生态系统。从管理面板和 CRM 到独立的软件包、CI、profiler,众多如 web sockets 服务器、队列管理器、支付集成这样的服务...... 可以拿得出手的东西太多了。
不过,这些框架是用于实际开发的。如果你需要纯粹的内容管理,像 WordPress 和 CraftCMS 这样的平台只会越来越好。
测试 PHP 生态系统当前状态的一种方法是查看 Packagist,它是 PHP 的主要 package 存储库。它呈指数级增长,每天大约有 2500 万次的下载量。公平地说,PHP 生态系统已经不再是过去的小输家了。
下面的图表,列出了包和版本的数量随时间的变化。
除了应用程序框架和 CMS,近年来异步框架也逐步兴起。
这些框架和服务器是用 PHP 或其他语言编写的,通过这些框架,用户可以实现真正的异步 PHP。Swoole、Amp 和 ReactPHP 都是很好的例子。
自从我们进入异步世界以来,像 web sockets 和具有大量 IO 的应用程序之类的东西已经与 PHP 世界息息相关。
在内部邮件列表(内核开发人员讨论如何开发该语言的地方)上也有关于将 libuv 添加到内核的讨论。
语言本身
虽然 async 和 await 功能都还不能用,但是在过去几年里,PHP 语言本身已经做了很多改进。下面列出了 PHP 的部分新特性:
Short Closures
Null coalescing operator
Trait
Typed properties
Spread operator
JIT compiler
FFI
Anonymous classes
Return type declarations
Contemporary cryptography
Generators
除了语言特性,我们也应该看一下语言的发展过程。虽然社区也会提出 RFCs,但一个活跃的核心志愿团队才是推动语言的发展的根本。
这些 RFCs 会在「内部」邮件列表中进行讨论。在添加新的语言特性之前,必须进行投票,获得至少 2/3 支持的 RFC 才能被写入内核。
大概有 100 个人有投票权,虽然他们不必对每个 RFC 都进行投票。这些人中必须包括核心团队的成员,因为他们要维护代码库。剩下的投票者主要是从 PHP 社区中挑选出来的,这些人包括 PHP 文档的维护者、整个 PHP 项目的贡献者以及 PHP 社区中的杰出开发人员。
虽然大多数核心开发都是在自愿的基础上完成的,但是作为核心 PHP 开发人员之一,Nikita Popov 最近已被 JetBrains 聘用,成为了全职的 PHP 开发者。另外,Linux 基金会最近也决定投资 Zend framework。这样的雇佣和收购确保了 PHP 未来发展的稳定性。
工具包
除了程序内核本身,PHP 工具包的数量也在不断增加。静态分析器 Psalm(由 Vimeo 创建)、Phan 和 PHPStan 都是很好的例子。
这些工具可以对 PHP 代码做静态分析,并会报告任何类型的错误、可能的 bug 等。在某种程度上,它们的功能几乎可以赶上 TypeScript 了,不过目前这种语言还无法实现源到源编译,因此不允许使用自定义语法。
尽管这意味着我们需要依赖 docblock,但 PHP 的最初创建者 Rasmus Lerdorf 确实提到了向内核添加静态分析引擎的想法。这个想法潜力巨大,但这是一项艰巨的任务。
为了像 JavaScript 那样实现源到源编译,PHP 开发者们也一直努力在用户端扩展 PHP 语法。一个名为 Pre 的项目就在做这样的事:将新的 PHP 语法转换为普通的 PHP 代码。
虽然 JavaScript 中已经实现了这个想法,但是只有提供合适的 IDE 和静态分析支持,它才能在 PHP 中工作。这个想法很有意思,但它还需要不断成长,才有可能成为「主流」。
结语
说了这么多,你仍然可以吐槽说 PHP 是一种蹩脚的语言。虽然它还是有一些缺点和 20 年的遗留问题,但我仍然热爱这门语言。
以我的经验来看,我能够写出可靠易维护且高质量的软件。我和客户对最终的结果也都是满意的。
虽然使用 PHP 还会有一些乱七八糟的事情,但如果使用得当,我认为它还是一个不错的网络开发选择。