接手一个三年没人管的代码库是什么体验

王尘宇 经验分享 3

2025年9月,我接了一个外包转内部的PHP项目。对方跟我说"功能都能用,就是偶尔有点慢"。我打开代码库的那一刻,发现上次commit是2022年6月。

三年没人管的代码库长什么样?我来给你描述一下:

第一眼:目录结构是猜谜游戏

根目录下面有三个文件夹叫"backup"、"bak"、"backup_old",每个里面都是几十个带日期后缀的PHP文件,不知道哪个是最新的。真正的业务代码散落在七八个位置——/inc/auth.php 和 /libs/check_login.php 干的是同一件事,但实现方式不一样。有一个叫 "yii2_basic_org_new_final2" 的文件夹,里面还有一个叫 "yii2_basic_org_new_final3" ——看到这个名字的时候我就知道前面的人也是接盘的。

第二眼:数据库是定时炸弹

MySQL 5.6版本,86张表,三分之一没建索引。用户表里"password"字段是明文存储。订单表有个"status"字段,值是中文——"已付款"、"已发货"、"已退款"——用enum存的,但enum里有一半的值实际订单里从来没用过。最离谱的是,有个定时任务每分钟执行一次SELECT * FROM orders(是的,不带WHERE条件),在内存里做筛选。这台服务器只有4G内存。

第三眼:依赖是考古现场

composer.json里锁了24个包。其中6个在Packagist上已经不存在了,3个的最后更新是2019年。有个phpmailer的版本是5.2,而这个版本在2020年就暴露过一个RCE漏洞(CVE-2020-36326)。我试着composer update了一下——整个项目白屏了。

我是怎么收拾残局的

第一步不是写代码,是建护栏。我先给整个项目套了一层Cloudflare的WAF,然后把数据库dump下来在本机搭了个Docker环境。生产环境一行都不碰。

第二步,花了整整一周画出调用关系图。没有文档,只能靠ripgrep全局搜函数名和类名,反向推到入口。画完发现:这个项目名义上有87个"功能模块",实际流量只集中在7个。剩下80个根本没人用——全是以前给不同客户定制的,客户早丢了,代码还在。

第三步,先砍再修。砍掉了14万行死代码(总共22万行),相当于三分之二都是僵尸。然后才开始加索引、升级依赖、修SQL注入。

学到的东西

1. 接盘项目的第一原则:不要相信"功能都能用"这句话。能用的定义是有测试用例跑通了才算。

2. 先搞清楚哪些代码真的在跑,哪些是僵尸。Nginx或Apache的access log比代码注释诚实一百倍。

3. 安全漏洞排优先级:先修能被外部触发的(XSS、SQL注入、文件上传),再修需要登录的,最后修需要管理员权限的。

4. 版本控制是你的救命稻草。接手项目第一件事,git init && git add -A && git commit -m "接手前的快照"。后面改崩了至少能回得来。

这个项目最后清了两个月才稳定上线。中间出过一次生产事故——把所有用户登出了——但因为有git记录和Docker环境,十分钟就回滚了。如果这个故事有什么教训,那就是:代码比你想象的还烂的时候,先别着急改,先把防线建好再说。

标签: 代码维护 PHP 项目复盘 技术债务 代码重构

发布评论 0条评论)

  • Refresh code

还木有评论哦,快来抢沙发吧~