编码标准

在前面的章节中,你学到了很多关于编写高质量代码的知识。然而,仅靠自己是不够的。当你在一个团队中工作时,很可能会遇到这样的问题:其它开发人员对质量的理解不同,技术水平也与你不同。

这对你的代码是有害的,因为它可能会导致懒惰的妥协,即相关各方同意一种方式,只是为了得到他们的平静。因此,如果你想在团队中高效地工作,就必须尽可能地实现工作标准化。

从 "低垂的果实" 开始:代码格式化。这就涉及到最基本的问题,比如商定缩进行应使用多少空格,或大括号应放在什么位置。但这又有什么重要的呢?

我们在第 5 章 "优化时间,分清责任" 中已经简要讨论过这个问题。不过,我们还是想在此进一步阐述。拥有一个通用的编码标准(也称为编码风格)的主要好处是减少阅读代码时的认知摩擦。

认知摩擦

认知摩擦主要是指我们的大脑在处理信息时所需要的脑力劳动。例如,想象一下,你在读一本书时,每隔一段都用不同的字体、大小或行距来书写。你仍然可以阅读,但很快就会感到厌烦或疲倦。阅读代码也是如此。

在项目中引入编码标准相对容易,这要归功于我们在本书前面介绍的工具。另一方面,与他人就共同标准达成一致则需要更多的工作。因此,在本节中,我们将向你展示如何轻松地就共同编码标准达成一致。

遵循现有标准

与他人一起制定标准可能是一个漫长而痛苦的过程。然而,如今人们不再为一张纸的尺寸争论不休。在欧洲国家,DIN A4 标准被广泛接受,而在美国等其它国家,你会使用 US Letter 尺寸,而不会问为什么。大多数人都接受这些尺度,遵循这些标准会让生活变得更轻松—​少了一件需要关心的事。

编码标准也是如此,它规定了代码的格式。当然,你可以与队友就缩进应该使用制表符还是空格争论几个小时。双方都会提出合理的论据,但你永远找不到正确的答案,因为这里根本没有对错之分。一旦你解决了缩进的问题,下一个要讨论的话题可能就是括号的位置。它们应该出现在同一行还是下一行?

我们不一定要同意标准的每一个细节,但毫无疑问,使用现有的规范可以节省时间和精力。在 PHP 生态系统中,有一些已经存在的编码标准可供使用。这样做的一个巨大额外好处是,代码嗅探器有针对这些标准的内置规则集。在下一节中,我们将讨论 PHP 最著名的编码标准。

PHP-FIG 和 PSR

PHP 本身没有正式的编码标准。从历史上看,每个主要的 PHP 框架,无论是已经存在的还是现在仍然存在的,都引入了某种标准,因为开发人员很快就意识到使用这些标准有其好处。

然而,由于每个项目都使用自己的标准,PHP 世界最终形成了不同格式标准的混合体。早在 2009 年,由当时所有重要 PHP 项目和框架的成员组成的 PHP 框架互操作性小组(PHP-FIG)成立时,他们就想解决这类问题。

当时,Composer 变得越来越重要,并推出了可以在不同框架间轻松使用的软件包。为了保持代码的一致性,大家商定了一种共同的代码编写方式:PHP 标准建议(PSR)应运而生。

为了让 Composer 的自动加载器正常工作,有必要就如何命名类和目录达成一致。第一个标准建议 PSR-0(是的,书呆子从 0 开始计数)就是这样做的,它最终被 PSR-4 所取代。

第一个编码标准建议是通过 PSR-1 和 PSR-2 提出的。PSR-2 后来被 PSR-12 取代,后者包含了针对较新 PHP 版本语言特点的规则。

尽管 PSR-12 涉及代码风格,但并不包括命名约定或如何构建代码。这通常还是由你使用的框架预先定义的。例如,Symfony 框架就有自己的一套编码标准,该标准以上述 PSR-4 和 PSR-12 为基础,但增加了更多的指导原则,例如命名或文档方面的约定。即使你完全不使用框架,而只是选择单一组件来构建应用程序,也可以考虑使用这些指南,你可以在 Symfony 网站上找到: https://symfony.com/doc/current/contributing/code/standards.html

PER 编码风格

PSR-12 于 2019 年发布,因此不再涵盖最新的 PHP 功能。因此,在编写本书时,PHP-FIG 发布了 PER 编码风格 1.0.0(PER 是 PHP Extended Recommendation 的缩写)。它以 PSR-12 为基础,并对其进行了一些补充。今后,PHP-FIG 不再计划发布任何与 PSR 相关的新编码标准,但会在需要时发布该 PER 的新版本。我们在本书中介绍的代码质量工具很可能很快就会采用新的 PER。你可以在这里找到更多相关信息: https://www.php-fig.org/per/coding-style

随着时间的推移,PHP-FIG 已经提出了十多项建议,更多的建议正在制定中。它们涵盖的主题包括如何集成日志、缓存和 HTTP 客户端等。你可以在官方网站 https://www.php-fig.org 上找到完整列表。

PHP-FIG 和 PSR 的问题

PHP-FIG 不应被视为 PHP 的官方权威,任何 PSR 也不应被视为无可争议。事实上,许多重要的框架(如 Symfony 或 Laravel)都不再是 PHP-FIG 的一部分,因为推荐标准对它们的内部结构干扰太大。纵观当今所有的 PSR,你甚至可以将它们视为自己的元框架。但这并不是要贬低许多建议的相关性—​我们只是希望你不要盲目地将它们视为理所当然。

在 IDE 中实施编码标准

有几种方法可以强制执行编码标准。在上一章,即 第 11 章 "持续集成" 中,我们介绍了如何确保格式错误的代码不会破坏代码库。这样做效果很好,但需要额外的步骤,即使我们让工具自动修复代码格式,因为我们需要再次提交这些更改的文件。那么,如果我们的代码编辑器或集成开发环境能在我们编写代码时帮助我们格式化代码,这是不是真的很有用呢?

现代代码编辑器通常都有内置功能,如果你进行了配置,它可以帮助你遵守你偏好的编码标准。如果没有内置功能,至少可以通过插件提供。

编辑器可以通过两种基本方式为你提供支持:

  • 突出显示违反编码标准的内容:集成开发环境会标记源代码中需要更正的部分。但它不会主动修改代码。

  • 重新格式化代码:集成开发环境或附加插件都会对代码进行格式化,例如,运行代码风格修正程序(如 PHP_CS_Fixer)。这可以根据手动请求或每次保存文件时进行。

在保存文件时重新格式化代码是确保代码符合编码标准的一种非常方便的方法。如何设置取决于你使用的集成开发环境,因此我们在本书中不再详述。

我们仍然建议使用 Git 钩子和持续集成作为第二层检查,以确保没有格式错误的代码被推送到项目仓库。你永远无法确定团队成员是否意外或自愿禁用了自动格式化,或者对代码中突出显示的部分不感兴趣。

编码标准主要涉及如何统一代码格式。但这并不是在团队中工作时应达成一致的全部内容,在下一节中,我们将向你介绍还有哪些方面值得达成一致。