大昔のウェブシステムでは、(たまにSmartyとかもありますが)バニラPHPで書かれたものが基本です。
今回、とあるウェブシステムをLaravelに書き換えリニューアルすることになったのですが、これが本当に読みづらい……。
<?php if($hoge): ?>
<?php echo h($hoge); ?>
<?php elseif($foo): ?>
<?php echo h($foo); ?>
<?php endif; ?>
驚くことに、昔はこれが見やすいと思っていたのですよ。しかしLaravelのBladeに慣れた今では読みにくくてたまりません。
一応、Larave(Blade)では素のPHP構文も動くようなので、このままでも問題は無いっぽい!?……ですが、さすがにこれでLaravel案件として納品するのははばかられます。
ということで該当箇所の修正を検討することにしました。
いくつかの方法がありますが、結論としてはVSCodeの正規表現で置き換えることに。業務で似たような状況が発生している方に対し、少しでも参考になるところがあれば幸いです。
そもそもの置き換える方法
今回はVSCodeでの置換に決めましたが、そもそも複数の方法があると思います。何が最適化はケースバイケースですので、念のため確認してみます。
手作業で置き換え
少なければ手作業もありなのかもしれません。
しかし今回、私の場合<?php
でページ内検索して100個を超えていました。
サイト全体だと途方もない数でしたので、端からこの方法は無しです。
AIに置き換えてもらう
例えばChatGPT等では、きちんと指示を出せば、比較的正確にBladeに置き換えてくれます。セキュリティ上の問題も無く、AIにコードを投げても大丈夫な場合は選択肢に入るでしょう。
私はChatGPTの有料版(Plus)を利用していますが、たしかデータは利用される認識です(最近の規約は見てませんが、そうですよね!?)。
セキュリティ的にある程度の意識が求められる案件なので、(明確にダメというわけではありませんが)リスクを考えやめました。
正規表現で置き換える
とうわけで今回はこの方法を採ることにします。でも、正規表現って難しいですよね。私はなかなか覚えられません。覚えても使わなければすぐ忘れてしまいます。
というわけで毎回調べながら(今回はChatGPTに教わりながら)やっていますが、せっかくなので今回は記録しておきたいと思った次第です。
冒頭で述べたとおり、VSCodeでの正規表現とします。正規表現自体は規格があるようですが、基本的には応用がきくケースが多いと思います。他のテキストエディタでもできるかもしれません。
置き換えについて
面倒臭いですが、コツコツと1つずつ正規表現で検索・置き換えていきます。
ページ内置き換えでも、サイト内置き換えでもどちらでも対応可能ですが、以下赤枠の様に、正規表現を利用できる状態にする必要があります。
ご注意
私自身、長年正規表現に触れてはいますが、深い知識は無く、そもそも興味もあまりありません。ただ対症療法的に使ってきた感じです。そのため本ページを過信しないでください。
今回、私のケースではおおよそ置き換わったのを確認しましたが、元々のコードの書き方によっては置き換わらなかったり、思いもよらない箇所までマッチ&置き換わってしまう可能性もあります。
置換の前はバックアップを取り、元に戻せるようにして実行してくださいね。特に一括置き換えにはご注意ください。
それでは、早速やっていきましょう!
if 文の置き換え
検索
<\?php\s+if\s*\(\s*(.*?)\s*\)\s*:\s*\?>
置き換え
@if($1)
elseif 文の置き換え
else if
など、空白を入れているケースも考慮しました。
検索
<\?php\s+(else\s*if|elseif)\s*\(\s*(.*?)\s*\)\s*:\s*\?>
置き換え
@elseif($2)
else 文の置き換え
正規表現を使うまでもないかもしれませんが一応。
検索
<\?php\s+else\s*:\s*\?>
置き換え
@else
endif 文の置き換え
検索
<\?php\s+endif\s*;\s*\?>
置き換え
@endif
foreach 文の置換($key => $valのみ)
foreach($datas as $key => $value)
のような、キーと値を渡すタイプです。
検索
<\?php\s+foreach\s*\(\s*(.*?)\s+as\s+(\$[a-zA-Z_][\w]*)\s*=>\s*(\$[a-zA-Z_][\w]*)\s*\)\s*:\s*\?>
置き換え
@foreach($1 as $2 => $3)
foreach 文の置換($valのみ)
foreach($datas as $value)
のような値のみのタイプです。
検索
<\?php\s+foreach\s*\((.*?)\s+as\s+(\$[a-zA-Z_][\w]*)\):\s*\?>
置き換え
@foreach($1 as $2)
endforeach 文の置換
これも正規表現は必要ではありませんが、空白の考慮など多少柔軟にマッチします。
検索
<\?php\s+endforeach\s*;\s*\?>
置き換え
@endforeach
for 文の置換
検索
<\?php\s+for\s*\((.*?)\)\s*:\s*\?>
置き換え
@for($1)
endfor 文の置換
検索
<\?php\s+endfor\s*;\s*\?>
置き換え
@endfor
while 文の置換(未検証)
検索
<\?php\s+while\s*\((.*?)\):\s*\?>
置き換え
@while($1)
endwhile 文の置換(未検証)
検索
<\?php endwhile; \?>
置き換え
@endwhile
h() の置換
基本構文以外の応用です。私のケースを元にしていますが、近い運用をされている方は参考になさってください。
htmlspechalchars
をラップした関数を利用している方は多いと思います。こんな感じです。
<?php echo h($hoge); ?>
ご利用の方のみ、置換の参考にしてください。
検索
<\?php\s+echo\s+h\((.*?)\);\s*\?>
置き換え
{{ $1 }}
nl2br(h()) の置換
頻出例として、以下のような改行を<br>に変換して出力するケースを想定しています。
<?php echo nl2br(h($hoge)); ?>
お問い合せフォームなどでよく使うはずですが、意味が分かる&ご利用の方のみご参考ください。
検索
<\?php\s+echo\s+nl2br\(h\((.*?)\)\);\s*\?>
置き換え
{!! nl2br(e($1)) !!}
$hoge['bar] の置き換え
バニラPHPでは、$hoge['bar']
や$hoge["bar"]
のようにモデルからのデータを配列で扱うことも今より多かったと思います。
これをLaravelにリニューアルすると、$hoge->bar
のようになるので置き換えます。
例に挙げたように、シングルクォートとダブルクォートの両方にマッチさせる必要があります。
検索
\$(\w+)\[["']([^"']+)["']\]
置き換え
$$
でドルマークを表現するようです。
$$$1->$2
{{ }}から {!! !!}の置き換え
{{ method($hoge) }}
などに置き換え後、エスケープさせたくないことがよくありましたのでこれを置き換える正規表現です。
検索
\{\{\s*(.+?)\s*\}\}
置き換え
一括置換だと通常のエスケープしたい内容も置き換わってしまうので、目視で1つずつ置換が必要だと思われます。
{!! $1 !!}
フォームのエラーメッセージの置き換え
ここからはより私固有の案件での対応も書いていきます。
今回は以下の様な、フォームのエラーメッセージを返している部分を、Laravel用に置き換えてみます。
<?php echo $form->error('name'); ?>
変数名やメソッド名が異なっても対応出来るようにしていますが、動かない場合も、少し変えるだけで応用できると思います。
検索
<\?php echo \$(\w+)->(\w+)\('([^']+)'\);? \?>
マッチしすぎてしまう場合は、以下の様に$form
とerror
のように変数名を固有にすると良いです。
<\?php echo \$form->error\('([^']+)'\) \?>
置き換え
@error('$3')
<div class="error">{{ $message }}</div>
@enderror
※変数名を$form
とerror
のように指定した場合は、$3
ではなく$1
となります。
フォームのエラーメッセージの置き換え(2)
先ほどのとかなり似ていますが、以下のようなコードがある案件を置き換えます。
<?php echo $this->error('detail'); ?>
検索
<\?php\s+echo\s+\$this->error\('([a-zA-Z_][\w]*)'\);\s*\?>
置き換え
@error('$1')
<div class="error">{{ $message }}</div>
@enderror
※変数名を$form
とerror
のように指定した場合は、$3
ではなく$1
となり
まとめ
以上で、大抵のウェブシステムではLaravelのBlade用に置き換わるかと思います。後は残る<?php
や?>
などを個別に検索して潰していけば、ほぼ網羅できることでしょう。
あなたの案件の、時間短縮につながれば幸いです。
コメント