pukiwikiプラグインをRectorPHPでphp8.1へ静的に自動修正させてみた


はじめに

そろそろ、pukiwiki 1.5.4がリリースされる予定らしく、php8ではJITコンパイラーが実装され、処理が高速になるそうなのでpukiwikiプラグインをすべてphp8で動くようにRectorPHPで自動修正させようと思います。
ただ、あくまで静的解析して修正するのでもちろんファイルによっては手動で修正しなければならないこともあります。
Windowsで動作させてます。
他のOSでも動作するとは思いますが、その場合は参考程度でお願いします。

完成したファイル

すぐに使いたい方は次の見出しからは読まなくても大丈夫です。
RectorPHPがMITライセンスだったのでGitHubにて配布しておきます。
tweakphp8.phpについてはこちらでつくりました。
これもMITライセンスとしておきます。

PHP8をインストールしているのであれば動作すると思います。
inputフォルダに修正したいpukiwikiプラグインを突っ込むんでstart.batを開くと実行されます。
自動で閉じられたら完了していると思います。
変換後のファイルがoutputフォルダにて生成されていると思います。

環境

  • composer
  • php8
  • pukiwiki-1.5.4rc
  • Windows 11

手順

  1. PHP8をインストール
  2. Composerをインストール
  3. RectorPHPの導入
  4. rector.phpの修正
  5. inputフォルダにpukiwikiプラグインを入れる

1~2の説明は省きます。
各自で調べるようお願いします。

RectorPHPの導入

  1. Windowsターミナル(コマンドプロンプトでも可)にてcomposer require rector/rector --devを実行
    RectorPHPに関するパッケージ等が生成されると思います。

  2. "vendor/bin/rector" initを実行します

  3. 生成されたrector.phpを以下のように編集します。(個人の好みの問題なのでしなくても結構だとは思いますが、この記事ではこの手順で説明します。)
    srcではなくoutputフォルダを指定する。

$parameters->set(Option::PATHS, [
    //__DIR__ . '/src'
    __DIR__ . '/output'
]);

4. tweakphp8.phpを作成する
名前が思いつかなかったのでtweakphp8.phpとかいうよくわからないファイル名にしちゃっています。ただの& newを除去するだけのPHPスクリプトなんですけどね^^;
"vendor/bin/rector" processを実行してみたのですが、& newが原因でエラーが出てしまったんですよね。筆者自身RectorPHPの仕様がまだよくわかってないんですよ( ̄▽ ̄)
なので適当に& newを削除するコードをつくってみました。

#!/usr/local/bin/php -q
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
    system('cls');
    echo chr(27).chr(91).'H'.chr(27).chr(91).'J';
} else {
    system('clear');
}

$input_dir = "./input/";
$output_dir = "./output/";

$options = getopt(null, ['input::', 'output::']);
if ($options['input'])
	$input_dir = $options['input'];
if ($options['output'])
	$output_dir = $options['output'];

foreach (glob("input/*.php") as $filename) {
	$contents = file_get_contents($filename);
	// rectorで修正できないっぽい?部分をここで直接修正
	$newContents = tweakphp8($contents);
	file_put_contents($output_dir . basename($filename), $newContents);
}

function tweakphp8($str) {
	$newLines = array();
	$instance = new TweakPHP8();
	
	$str = str_replace(array("\r\n","\r"), "\n", $str);
	$lines = explode("\n", $str);
	
	foreach ($lines as $line) {
		$newLine = $instance -> convert($line);
		if ($newLine !== false) {
			$newLines[] = $newLine;
		}
	}
	$newStr = implode("\n", $newLines);
	return $newStr;
}

class TweakPHP8 {
	public function convert($line) {
		$cmt = false;
		$body = false;
		if (preg_match("/^(.*?)(\/\/.*?)$/", $line, $m)) {
			$body = $m[1];
			$cmt = $m[2];
		} else {
			$body = $line;
		}
		$body = preg_replace("/&\s*?new/", "new", $body);
		
		return ($body ? $body : '') . ($cmt ? $cmt : '');
	}
}

今思うと静的関数にしてもよかったと思いますね^^
というかクラス自体不要だったのではと思いましたが、そもそもRectorPHPに気付かず最初は自動修正ツールをつくりかけてたバカです笑

5. pukiwikiプラグインをinputフォルダに入れる

6. バッチファイルの作成

php tweakphp8.php --input="./input/" --output="./output/"
"vendor/bin/rector" process

さいごに

主に配列の書式である{0}を[0]へ、コンストラクタを__constructに修正していると思います。なぜか&newについては修正してくれないようです^^;
include関数のように配列のみ指定しないといけない関数に仕様変更されているものについては手直ししないといけません。
このようにコードによっては手直ししないといけない部分もあるとは思いますが、エラーを調べると解決策が出てくるとは思いますので簡単に直せると思います。
何かあればご指摘お願いします。

参考