旧属性平滑升级的核心是构建可验证、可回退、语义不变的重构流水线;需先识别public成员变量、数组式属性、全局配置项、魔术属性等目标,再用PHPStan/ Psalm扫描,Rector自动生成getter/setter骨架。

要让旧属性平滑升级为标准方法,核心不是“一键运行脚本”,而是构建一个可验证、可回退、语义不变的重构流水线。关键在于把“属性访问”这种隐式行为,显式转化为符合现代规范的封装方法(如 getter/setter),同时确保所有调用点自动适配、不破坏功能。
明确哪些旧属性需要升级
先识别目标,避免盲目替换。常见需升级的旧属性包括:
- public 成员变量直接读写(如
$user->name) - 未封装的数组式属性(如
$config['db_host']) - 全局或静态变量暴露的配置项(如
CONFIG_DB_HOST) - 魔术属性(
__get/__set中未统一校验的字段)
建议用 PHPStan 或 Psalm 扫描出所有未声明类型、无访问控制的属性,并导出清单作为重构输入。
用 Rector 自动注入标准方法骨架
Rector 是目前最可靠的自动化工具,支持按版本渐进生成 getter/setter,并保留原有逻辑。配置示例如下:
<?php
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\SetList;
return RectorConfig::configure()
->withPaths(['src/'])
->withSets([
SetList::CODE_QUALITY, // 启用基础质量规则
SetList::PHP_80, // 确保语法兼容性
])
->withRules([
\Rector\Php80\Rector\Class_\ReorderPropertiesAndConstantsRector::class,
\Rector\CodeQuality\Rector\Class_\InlineConstructorSettersRector::class,
\Rector\CodeQuality\Rector\Class_\AddGetterAndSetterMethodRector::class,
]);
执行命令:vendor/bin/rector process src/ --dry-run 预览变更;确认无误后去掉 --dry-run 实际应用。
保持向后兼容:代理旧属性访问
升级后不能让老代码崩掉。Rector 生成的方法默认不接管旧属性访问,需手动加一层兼容层:
- 在类中保留原 public 属性(暂不删),但标注
@deprecated - 重写
__get()和__set(),将对属性的读写转发到新方法:if ($name === 'name') { return $this->getName(); } - 对数组式配置,封装成
Config::get('db_host'),内部仍支持旧键名映射
这样既启用新方法,又不中断现有调用,为后续彻底移除旧属性留出缓冲期。
验证无损:用测试+差异比对双保险
重构是否真正“无损”,必须靠证据说话:
- 运行全部单元测试,确保覆盖率不低于 90%;特别关注涉及该属性的边界 case
- 用
git diff对比重构前后运行时输出(如 API 响应 JSON、日志内容) - 对关键对象做序列化对比:
serialize($obj) === serialize($objAfterRefactor)(排除引用和时间戳等干扰)
若项目无测试,至少用 var_export() 抓取典型实例的完整状态快照,作为人工回归基线。

















