RectrorPHPによるFuelPHPからLaravelの移行の自動化
はじめに
弊社のプロダクトはFuelPHPで書かれたものが多いのですが、これらをLaravelに移行するにあたり、可能な部分は機械的に変換することにしました。
今回取り上げるRectorPHPは、PHPコードのリファクタリングやコードの自動修正を行うためのなツールです。本記事では、RectorPHPを導入し、独自のリファクタリングルールを書く方法について紹介します。
RectorPHPのインストール
1. composerのインストール
まずはcomposerをインストールします。composerはPHPの依存関係管理ツールで、RectorPHPのインストールに必要なものです。
curl -sS https://getcomposer.org/installer | php
2. RectorPHPのインストール
次にRectorPHPをインストールします。以下のコマンドを使用して、RectorPHPをプロジェクトに追加します。開発環境でしか使わないのでdevオプションをつけています。
composer require rector/rector:"^0.15.24" --dev
これにより、プロジェクトの composer.json ファイルが更新されます。
3. composer.jsonの更新内容
RectorPHPのインストールにより、composer.json ファイルに以下のような変更が加わります。ここではautoloadの指定も行っています。
{
"require-dev": {
"rector/rector": "^0.15.24",
},
"autoload-dev": {
"psr-4": {
"Utils\\Rector\\": "utils/rector/src",
"Utils\\Rector\\Tests\\": "utils/rector/tests"
}
}
}
これでRectorPHPがプロジェクトに追加されました。
独自ルールの書き方
RectorPHPを使用して独自のリファクタリングルールを書くには、以下の手順に従います。
1. ルールの作成
変換ルールのロジック部分を作成します。今回はInsertRule1.phpという名前で作成しました。
<?php
declare(strict_types=1);
namespace Utils\Rector\Rector\QueryBuilder\Insert;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
final class InsertRule1 extends AbstractRector
{
public function getNodeTypes(): array
{
return [MethodCall::class];
}
public function refactor(Node $executeNode): ?Node
{
if (!$this->isName($executeNode->name, 'execute')) {
return null;
}
$setNode = $executeNode->var;
if (!$setNode instanceof MethodCall || !$this->isName($setNode->name, 'set')) {
return null;
}
$insertNode = $setNode->var;
if (!$insertNode instanceof StaticCall || !$this->isName($insertNode->name, 'insert')) {
return null;
}
return new MethodCall(
new StaticCall(
new Node\Name\FullyQualified('DB'),
new Node\Identifier('table'),
$insertNode->args
),
$insertNode->name,
$setNode->args
);
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Change method calls insert',
[
new CodeSample(
// code before
"\DB::insert('table_name')->set(['name' = > 'alice', 'age' => '20'])->execute();",
// code after
"\DB::table('table_name')->insert(['name' = > 'alice', 'age' => '20']);"
),
]
);
}
}
2. ルールの登録
最後に、作成したRectorクラスをrector.phpファイルに登録します。
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Utils\Rector\Rector\QueryBuilder\Insert\InsertRule1;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/app',
__DIR__ . '/bootstrap',
__DIR__ . '/config',
__DIR__ . '/public',
__DIR__ . '/resources',
__DIR__ . '/routes',
__DIR__ . '/tests',
]);
$rectorConfig->rules([
InsertRule1::class,
]);
};
InsertRule1::classをルールとして適用しています。
これで独自のリファクタリングルールがRectorPHPに追加されます。
3. ルールの実行
テスト実行をしてみます。パラメータにdry-runをつけるとテストになります。
bash5.2# vendor/bin/rector process ./rector_src/Models/ --config rector.model2.php --dry-run
このように置き換えられた様子を確認できます。
おわりに
本記事では、RectorPHPの導入と独自のリファクタリングルールの作成方法について紹介しました。RectorPHPを使用することで、PHPプロジェクトのコードベースを効率的に改善することができます。是非、ご自身のプロジェクトにも導入してみてください。