重构优化分析.md 8.1 KB

祈盟SDK - Go重构优化分析

不是简单搬代码,而是借重构机会解决历史债务


一、现有代码核心问题

1. common.php 全局函数地狱(1988行,90+函数)

这是项目最大的技术债。所有工具函数堆在一个文件里,没有分类、没有接口约束。

1.1 HTTP请求函数重复(5+个)

函数名 行数 功能
getCurlContent 366 原始curl,支持POST
getCurl 1252 GET请求封装
curl 1282 通用curl封装
apipost 1214 POST请求封装
getHttp 1652 通用HTTP,支持GET/POST
getHttpGet 1702 GET请求,带JSON支持
getHttpException 1722 POST请求,带header
curlHeader 1439 带header的curl
timingCurl 1386 超时curl

问题: 9个函数做同一件事,各自有不同的参数风格、错误处理方式、超时设置。调用方随机选用。

Go重构建议: 统一为一个 HttpClient 结构体,提供 Get / Post / PostJSON 方法,统一超时、重试、日志。

1.2 数据脱敏函数重复(6个)

stringObfuscation()    - 通用字符串脱敏
idcardObfuscation()    - 身份证脱敏
passwordObfuscation()  - 密码脱敏
mobileObfuscation()    - 手机号脱敏
usernameObfuscation()  - 用户名脱敏
mailObfuscation()      - 邮箱脱敏

问题: 6个函数逻辑几乎相同,只是保留位数不同。

Go重构建议: 一个 Mask(s string, keepStart, keepEnd int) 函数搞定,或用 MaskMobile / MaskIDCard 等语义化方法包装。

1.3 渠道查询函数重复(8+个)

get_top_channel()                // 查顶级渠道 - while循环逐级查parent_id
get_union_channel()              // 查联盟渠道 - 几乎相同的while循环
get_channel_level()              // 查渠道等级
get_top_second_channel_name()    // 查顶级二级渠道名 - 又一个while循环
get_top_second_channel_name_v2() // v2优化版 - 注释说"原版N次SQL优化为2次"
get_channel_top_by_aggregate()   // 聚合渠道顶级
get_channel_name()               // 查渠道名
get_complex_channel_name()       // 查聚合渠道名

问题:

  • 同一张表 nw_channel,8个函数各查一遍
  • get_top_second_channel_name_v2 注释已经说明原版有性能问题(N次SQL),但原版没删
  • 每个函数都独立查DB+缓存,缓存策略不统一

Go重构建议: 一个 ChannelService,提供 GetAncestors(channelId) 返回完整祖先链,所有上层查询都从这个方法派生。缓存统一管理。

1.4 安全问题

// 硬编码加密密钥(第1269-1278行)
function opensslEncrypt($data) {
    $key = 'ukN3KYVdI2sPtjpL';  // 硬编码!
    return base64_encode(openssl_encrypt($data, 'AES-128-ECB', $key, 0));
}

// 调试函数遗留生产环境(第1241行)
function dd() {
    echo Db::getLastSql();
    die;
}

// die()暴露内部信息
die('订单生成失败'.$e->getMessage());
die('签名校验失败 ' . $thisSign);
die('用于验签的参数还未设置');

Go重构建议:

  • 密钥走配置/环境变量
  • 移除所有调试函数
  • 错误信息统一返回码,不暴露内部细节

2. 聚合渠道回调:19个控制器文件,代码复制粘贴

application/complex/controller/ 下有19个渠道文件:

Aidou.php, Fengteng.php, Huwei.php, Juside.php, Qixin.php,
Shunyouanr.php, Shunyouios.php, Simo.php, Simoquick.php,
Vyou.php, Xiaozhi.php, Xigu.php, Xkhyn.php, Yiniu.php,
Ziyou.php, Zoulboom.php, Dii.php, Aoyou.php, Complex.php(基类)

每个子类的 pay() 方法结构完全相同:

  1. 接收POST参数(字段名不同)
  2. 调用 $this->checkOrder() 验证订单
  3. 获取验签参数
  4. 签名校验(算法不同)
  5. 事务写库 + 通知CP

唯一的差异:

  • POST参数字段名(orderid vs m_order_no vs cp_orderno
  • 签名算法(md5拼接 vs 自定义sign方法)

Go重构建议: 策略模式

type ChannelAdapter interface {
    ParseParams(r *http.Request) (*PayNotify, error)
    VerifySign(params map[string]string, appkey string) bool
}

// 注册表
var adapters = map[string]ChannelAdapter{
    "aidou":     &AidouAdapter{},
    "fengteng":  &FengtengAdapter{},
    // ...
}

// 统一回调处理
func HandlePayNotify(channel string, w http.ResponseWriter, r *http.Request) {
    adapter := adapters[channel]
    params, _ := adapter.ParseParams(r)
    // ... 统一的验单、签名、写库、通知逻辑
}

3. 接口版本混乱

问题 示例
v1/v2并存无规律 /v1.login/index.html(v1) vs /v2.user/userinfo(v2)
弃用接口未清理 /v2.game_notify/index_v2 注释"准备弃用"
已弃用仍在线 /v2.complex_authentication/query 标记"(弃用)"
路径风格混乱 .html后缀 vs 无后缀;有/index.html vs 直接方法名
命名大小写混用 /v2.Captcha/getCaptcha vs /v2.forget/resetPwdSendCode

Go重构建议:

  • 统一API路径风格: /api/v1/users/login(RESTful)
  • 弃用接口直接删除,不带到新系统
  • 路径全小写,用 - 分隔

4. Service层代码管理混乱

GamePayService.php
GamePayService_bak.php    ← 备份文件
MemberCoinService.php
MemberCoinService_bak.php ← 备份文件

问题: 用 _bak 做版本管理,说明:

  • 没有使用 Git 分支/标签
  • 不确定哪个是最新版
  • 重构时需要对比两个文件确认

Go重构建议: 直接丢弃 _bak 文件,只参考当前版本。如果当前版本有明显问题,基于业务需求重写。


5. 151个Model - 存在大量废弃

快速验证方法: 检查每个model是否还有控制器在引用。

Go重构建议: 不要1:1迁移model。先梳理核心数据表,只迁移有业务流量的表对应的model。


6. 其他问题

问题 说明 Go建议
die() 做错误处理 19个渠道控制器都用 die() 终止 用 error 返回 + 统一错误响应
unserialize() 反序列化 从DB取参数后直接 unserialize 用 JSON 存储,避免PHP反序列化漏洞
$_POST 直接取参 没有过滤/验证 用结构体绑定 + 自动验证
日志路径硬编码 LOG_PATH . '../complexPaylog/' 配置化,统一日志组件
can_do_request 限流 内联在业务代码中 中间件实现限流
缓存策略碎片化 各函数自己管理缓存TTL 统一缓存层,配置化TTL

二、Go重构优先级(建议顺序)

P0 - 核心支付链路(必须先做)

  1. 统一回调处理器 - 替代19个渠道控制器
  2. 支付服务 - 下单、查询、回调处理
  3. 订单服务 - 订单CRUD、状态机

P1 - 用户体系

  1. 认证服务 - 登录、注册、Token管理
  2. 用户服务 - 用户信息、实名认证
  3. 短信/验证码服务 - 统一验证码发送

P2 - 增值功能

  1. 代金券服务
  2. 礼包服务
  3. 充值服务

P3 - 辅助功能

  1. 渠道管理服务 - 替代8个渠道查询函数
  2. 配置服务 - 替代散落各处的配置读取
  3. 通知服务 - 钉钉告警等

三、不建议迁移的内容

内容 原因
_bak 文件 废弃代码
dd() 等调试函数 调试遗留
is_mobile_request() 现代浏览器UA已不适用
arrayColumnByObject() PHP7.0+已有 array_column
v2.game_notify/index_v2 已标记弃用
v2.complex_authentication/query 已标记弃用
gh/channel_data_summary 已被v2替代
所有 die() 错误处理 改为标准错误响应

四、需要确认的问题

在开始Go重构前,建议确认:

  1. 渠道回调: 19个渠道哪些还在用?可以联系业务方确认,废弃的直接不迁移
  2. v1接口: 哪些v1接口客户端还在调用?能否强制升级到v2
  3. 数据表: 151个model对应的实际表,哪些还有数据在写入
  4. 第三方SDK: 抖音、支付宝等SDK是否需要更新到最新版本
  5. 签名规则: 现有签名算法是否需要兼容,还是可以统一新规则