如何使用Rector在目标代码行上方插入新代码行?
问题说明
现有代码:
$last_data=date("Y-m-d",strtotime(mysql_result($res,0,0)));
目标重构代码:
$tmp_date_string=mysql_result($res,0,0); $last_data=date("Y-m-d",strtotime($tmp_date_string));
请问Rector能否在目标代码行上方插入新行?如果可以,具体操作方法是什么?
答案
可以,Rector完全支持在目标代码行上方插入新行,通过编写自定义规则即可实现,具体步骤如下:
步骤1:创建自定义Rector规则类
继承AbstractRector,重写核心方法识别并处理目标代码结构:use PhpParser\Node; use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\Variable; use Rector\Core\Rector\AbstractRector; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; class ExtractMysqlResultToVariableRector extends AbstractRector { public function getNodeTypes(): array { // 定位赋值语句节点 return [Assign::class]; } public function refactor(Node $node): ?Node { /** @var Assign $node */ $rightExpr = $node->expr; // 校验右侧是否为嵌套的date()→strtotime()→mysql_result()结构 if (! $rightExpr instanceof FuncCall || ! $this->isName($rightExpr->name, 'date')) { return null; } $strtotimeCall = $rightExpr->args[1]->value ?? null; if (! $strtotimeCall instanceof FuncCall || ! $this->isName($strtotimeCall->name, 'strtotime')) { return null; } $mysqlResultCall = $strtotimeCall->args[0]->value ?? null; if (! $mysqlResultCall instanceof FuncCall || ! $this->isName($mysqlResultCall->name, 'mysql_result')) { return null; } // 创建新变量赋值语句:$tmp_date_string = mysql_result(...) $newAssign = new Assign( new Variable('tmp_date_string'), $mysqlResultCall ); // 将原strtotime()的参数替换为新变量 $strtotimeCall->args[0] = new \PhpParser\Node\Arg(new Variable('tmp_date_string')); // 在原语句上方插入新赋值语句 $this->nodesToAddCollector->addNodeBeforeNode($newAssign, $node); return $node; } public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( '把嵌套在date/strtotime里的mysql_result调用提取为单独变量', [] ); } }步骤2:配置Rector加载自定义规则
在rector.php中注册该规则:use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use YourNamespace\ExtractMysqlResultToVariableRector; return static function (ContainerConfigurator $containerConfigurator): void { $services = $containerConfigurator->services(); $services->set(ExtractMysqlResultToVariableRector::class); };步骤3:运行Rector执行重构
执行命令完成代码修改:rector process your-target-file.php
注:你提供的目标代码存在语法错误(多写/少写括号),上述规则生成的代码会自动保持语法正确性。
内容的提问来源于stack exchange,提问作者realtebo
相关产品推荐
相关产品推荐

