PHP Manual
/
安全问题

重构一个遗留的PHP项目--如何追赶技术债务

11. 05. 2021

Obsah článku

在向知识渊博、经验丰富的项目负责人咨询时,我经常遇到数字项目的长期可持续性问题。许多超过3年开发的大型项目开始变得内部过时,不再具有可持续性--现在想象一下,一个由知识、经验和最重要的勤奋程度不同的开发人员组成的团队。

为了使你的数字项目在技术上保持最高水平,你需要。

  • 有能力的开发人员和一个项目经理,他们有很好的沟通,每个人都知道自己在做什么,以及对其他人有什么影响。
  • 功能工具和工作流程,整个团队都知道,并相应地调整他们的工作给他人。
  • 自动化的任务,提供了一个很容易忘记的日常工作,这一点极为重要。

如果你正在开发一个大型项目,你根本不容易。做好事情很重要,但做正确的事情更重要。

什么是重构,为什么需要它

重构的概念包含了一组活动,在不影响周围环境的情况下,修改程序代码的外观和内部逻辑。你可以把重构过程看成是一次圣诞大扫除--它保持原样,但更有条理,不必要的东西被扔掉了。对于重构,同样重要的是要记住这不是一个一次性的事件,而是一个长期的过程,你必须在定期的周期中重复。如果你不这样做,你就会出现各种奇怪的错误、财务损失、入职问题和叫苦不迭。

如果你能保持项目的稳定和及时更新,你将获得一些巨大的好处。

  • 该项目将是***的。你所使用的库内会定期发布错误和安全漏洞的补丁。你必须解决安全问题,它是一个健康项目的基本生命功能之一。
  • 代码和内部架构将变得更简单,考虑得更周全。你将能更好地发现Bug,许多Bug甚至可以被预防。
  • 通过简化代码,您还可以引入初级开发人员,以大幅减少您的总体预算。
  • 你可能会发现,你把一些事情做得太复杂,过于繁琐--项目总体上会被简化。

为了保持一个大型数字项目的正常运行,你必须跑步。但你想成长。

如何安全地进行重构

每一次重构都是一个大赌注,可能不会得到回报。

在开始重构之前,我总是先确保一个稳定的环境。

为了稳定,你特别需要功能的错误记录。对于简单的项目,你只需要Tracy,它将错误记录到一个HTML文件。对于更高级的项目,像SentryRollbar这样的工具就可以发挥作用。我个人在所有项目上都使用Tracy,其他工具则取决于项目类型。

在重构前一个月左右,我开始跟踪bug,并创建一个已知bug的电子表格,以便以后重点关注。了解哪些bug是由重构引入的,哪些是项目在过去已经包含的,总是很重要的。然后,这将有助于向客户更好地捍卫工作成果。

一旦我知道,由于日志,我在一个相对稳定的环境中工作,我们就可以开始艰苦的工作了。其他标题包括根据这些方法背后潜藏的风险程度对其进行描述。

固定编码风格和编码标准

大多数项目都没有统一的代码格式风格。这是个大错误。一个写得好的项目看起来像一个人的项目,所有的东西都写得一样。

基本的格式化错误通过我定期在整个项目上运行的Nette代码检查器工具得到了很好的纠正。

另一方面,编码风格涵盖了代码的格式化和单个语言表达的缩进。PSR-12标准在PHP世界中被大量使用,非常多的其他标准是基于它的。我建议使用。

一些项目尴尬地结合了tabs和空格。为了有效地防止破坏空白惯例(和其他错误),在项目根部创建一个.editorconfig文件,告诉你的编辑器如何格式化新写的代码。

我个人使用这种配置。

root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.{php,phpt}]
indent_style = tab
indent_size = 4

另外,将所有carrier-notees改为撇号。它可以自动完成。

你也可以自动检查你的代码的格式,我已经为此在GitHub上准备了一个功能齐全的演示。如果你还需要自动更正代码,这可以用同一个工具完成。PhpStorm也非常善于直接自动修正代码,甚至在整个项目中批量修正。

如何修复大型项目的编码风格

对于大型项目,我建议你一次只做一个模块的自动代码格式化,因为这样会在Git中产生大量的冲突。因此,最好的策略是用一个大的提交来修复尽可能多的行,把这个提交直接推送到主干,然后再把这个改动分发给其他分支。

如果冲突太大,先在主干上格式化代码,然后在有大量修改的每个大分支上再格式化一次,是有意义的。非常多的变化线会相互抵消(做一个快进),所以你会解决非常少的冲突,或者有时没有冲突。

如果你什么都不做,代码仍然会是坏的。多年来的反复重写肯定是行不通的,因为每次合并都需要修复几十行实际上没有发生变化的地方,而且会不必要地使代码审查和潜在的修改恢复变得复杂。

PhpStan - 静态代码分析和类型错误纠正

在着手进行大规模的逻辑修复之前,审查和修复**基本的项目生命周期特征是非常重要的。这些包括你从任何项目中期待的这种明显的东西,但有时仍然没有得到满足。

比如说。

  • 所有的类、方法和函数都必须存在
  • 不能破坏类的继承性
  • 类必须实现所使用的接口或祖先接口。同时,你不能继承最终
  • 你不能调用不安全的函数,如eval()shell_exec()var_dump()等等。如果你还是给他们打电话,必须在评论中明确说明
  • 你必须始终捕捉异常,不要让整个应用程序崩溃。

解决这个问题的方法是在项目中安装PhpStan,并将其至少修复到1级。是的,这很难,是的,这是个很大的工作。但如果你不这样做,每次重构都会变成俄罗斯轮盘赌,而开发者只是希望损失尽可能小。

PhpStan的基础层并不要求数据类型和其他正式的东西到处存在,例如,我们将在未来解决这个问题。另一方面,可能并不是一个函数或方法将返回某种数据类型,但在类型提示中却断言了其他的东西。

校长--安全的迭代式修复

一个著名的编程箴言说,在给系统添加一个新的错误(比如抛出一个异常)之前,我们应该先把这个错误作为一个警告,如果它长时间不表现出来,才把它变成一个致命的错误。

这与数据类型是一样的。在重构未知的代码时,我让像Rector这样的自动工具先给代码添加注释,这不会破坏任何东西,但有助于明确以后什么地方会出现。这些评论会被PhpStan监听,它可以用来安全地验证我们没有破坏任何东西,是一个安全的修改。

我一般在一次提交中为属性和参数添加注释,然后等待可能一个月,当一切都能长期工作时,我就在长期没有问题的地方采用改写为固定数据类型的方法。

请参阅文章我们如何在一天内完成数千个缺失的@var注解

关于Rector的更多信息,请参见GitHub

更新依赖关系

在进入更新软件包甚至是PHP版本的依赖关系之前,研究和学习如何使用自动测试很重要。

如果测试正常,我们可以到Composer工具中进行更新。如果可以的话,可以寻求Dependabot机器人的帮助,它可以自动更新你的项目的composer.json,并可以检查兼容性的变化。

如果你有一组大的变化,总是慢慢地做,并逐版递增。不要同时更新许多软件包。每次更新后,用PhpStan扫描整个项目并修复错误。这是一个漫长的过程,需要几个小时,但风险很高。

下一步该去哪里

接下来的步骤取决于项目的类型和状态,是个性化的。一般来说,由高级开发人员编写的精心设计的代码比从一个在媒体机构工作的初级人员那里廉价买来的代码要好得多,因为后者更多的是把网络开发作为一个副业,可以说。

祈祷吧!这将是艰难的,但你会渡过难关。

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
10.
Status:
All systems normal.
2024