投稿日:2024年8月31日

引き続きLaravelで申し込みフォームを制作しています。
申し込みフォーム単体としては申し分のない作りに仕上がり、仕事で無事にリリースできました。

しかし、毎回、項目をカスタマイズし、その都度、index、confirm、FormRequestの処理、データベースのリセットなどを個別に行わないといけないと思うとゲンナリします。

そこで、選択した項目によって自動的にindex、confirm、FormRequestなどに、必要な記述を書き出すアプリを作ろうと取り組んでいます。

今回は、JavaScript(jQuery)Laravel(PHP)間での、正規表現JSONでのデータの受け渡しでハマったことをお伝えしたいと思います。

▼この動画のように必要な項目チェックを入れてsubmitするとindex、confirm、FormRequstなどに必要な記述を出力する仕様にします。

 概要

▼開発途中の画面です。

management.blade.phpとしてページを作成。手順は以下。
❶出力したい項目にチェックを入れ、出力ボタンをクリックする。
❷それぞれのtextareajQueryで文字列としてタグを書き出します。
❸ミドルウェアでtextareaに記述されている内容を取得し、中間ファイル、indexPage.blade.phpconfirmPage.blade.phprules.jsonattributes.jsonに書き出します。
indexPage.blade.phpindex.blade.phpへ、confirmPage.blade.phpconfirm.blade.phpからinclude()で読み込みます。
rules.jsonattributes.jsonは、FormRequest.phpに読み込みます。

言葉だけでは分かりづらいので図にしてみました。

▼それぞれのファイルへ書き出す❸のミドルウェア TagOutputMiddleware.php です。

class TagOutputMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        // ▼ viewのindex、confirmへ書き出し
        $indexTagTxt = $request -> input('indexTag'); //management.blade.phpのindex.blade.phpへ出力タグ
        $confirmTagTxt = $request -> input('confirmTag'); //management.blade.phpのconfirm.blade.phpへ出力タグ
        
        // ▼ バリデーション、FomRequest.phpへ書き出し
        $rulesTxt = $request -> input('rulesTag'); ////management.blade.phpのrules.jsonへ出力タグ
        $attributesTxt = $request -> input('attributesTag'); ////management.blade.phpのattributes.jsonへ出力タグ
        
        // ▼ requestへマージ   
        $request -> merge([
            'indexTagTxt' => $indexTagTxt,
            'confirmTagTxt' => $confirmTagTxt,
            'rulesTxt'=>$rulesTxt,
            'attributesTxt'=>$attributesTxt
        ]);
        return $next($request);
    }
}
Route::get('/management', [FormController::class, 'management'])->name('management');
Route::post('/management', [FormController::class, 'management'])
        ->middleware(TagOutputMiddleware::class) //タグ書き出し
        ->name('management');

▲ルーティング。postで割り込みます。

 ハマったこと

今回ハマったのは上記の工程で用意したjQueryの下記の記述です。
電話番号のバリデーションを書き出すため、phpの連装配列を文字列として出力していました。

var telRequiredTxt = `'tel'=>['required', 
'regex:/\A(((0(\d{1}[-(]?\d{4}|\d{2}[-(]?\d{3}|
\d{3}[-(]?\d{2}|\d{4}[-(]?\d{1}|[5789]0[-(]?\d{4})[-)]?)|
\d{1,4}\-?)\d{4}|0120[-(]?\d{3}[-)]?\d{3})\z/'],\n`;

PHPでのバリデーションをそのまま文字列として出力していました。
dd()関数で出力すると下図のようにnullになってしまいます。

FormRequest.phpの受け取りが悪いのか? と、なんと一週間もハマってしまいました。

var telRequiredTxt = `,"tel":["required", 
"regex:/\\\\A(((0(\\\\d{1}[-(]?\\\\d{4}|\\\\d{2}[-(]?\\\\d{3}|\\\\d{3}[-(]?\\\\d{2}|
\\\\d{4}[-(]?\\\\d{1}|[5789]0[-(]?\\\\d{4})[-)]?)|\\\\d{1,4}\-?)\\\\d{4}|
0120[-(]?\\\\d{3}[-)]?\\\\d{3})\\\\z/"]\n`;

正しくは、こう書きます。
例えば \\\\A のように、エスケープ処理するためにバックスラッシュを4つ入れてます。
通常通り \A のように記述するとjsonに書き出した際、下図のようにバックスラッシュが脱落してしまいます。これにも2日くらいハマってしまいました。

▲バックスラッシュ1つでjsonファイルに書き出した結果。

▲バックスラッシュ4つで書き出すと、2つ出力されます。
JavaScriptではバックスラッシュ4つが正しい書き方になります。
つまり、PHPに渡した際、PHPでのjson_encodeのため、エスケープ文字のエスケープということです。
▼正しい動作になりました。

まとめ

ここ数ヶ月でようやく仕事での活用に至りました。
サーバーへのデプロイ後も、確認メールが迷惑メールに届くなど、エンベロープfromの設定などでもハマりましたが、この辺は別の機会にお伝えしたいと思います。

ユーザーにログインさせたいなどの要望もあるので、引き続き習得して行きたいと思います。

最後までお読みいただき、ありがとうございます。

Laravel関連の記事
Pocket