🐘
PHP 8.5のパイプ演算子を使ってお問い合わせフォームをワンライナーで作ってみた
注意
⚠本記事の内容およびコードは実験です。プロダクトに利用しないでください。
はじめに
PHP8.5でパイプ演算子が使えるようになります。パイプ演算子を使えば一行でお問合せフォームを作ることができるのでは…?と思いましたので試してみました。
パイプ演算子の概要
パイプ演算子は 左辺 |> 右辺 と書き、左辺の結果を右辺に渡して処理を連結できます。左辺の結果を即時実行関数の引数で利用できます。
echo 0.12
|> (fn($x) => $x * 100)
|> (fn($x) => $x . '%');
// 結果: 12%
フロー
コード
echo null
// CSRFトークンを生成
|> (fn() => (session_start() || true) && ($_SESSION['csrf_token'] ??= bin2hex(random_bytes(32))))
// POSTデータを取得
|> (fn() => $_POST)
// POSTデータをサニタイズ
|> (fn($post) => ['name' => htmlspecialchars($post['name'] ?? '', ENT_QUOTES, 'UTF-8'), 'email' => htmlspecialchars($post['email'] ?? '', ENT_QUOTES, 'UTF-8'), 'step' => $post['step'] ?? 'input', 'csrf_token' => $post['csrf_token'] ?? ''])
// バリデーション
|> (fn($params) => $params + ['errors' => array_filter([($params['csrf_token'] !== ($_SESSION['csrf_token'] ?? '')) && isset($_POST['step']) ? '無効なリクエストです' : null, (isset($_POST['step']) && $_POST['step'] !== 'input') && empty($params['name']) ? '名前は必須です' : null, (isset($_POST['step']) && $_POST['step'] !== 'input') && empty($params['email']) ? 'メールは必須です' : null])])
// ビュー
|> (fn($params) =>
[
'input' => '<form action="index.php" method="post">' . (count($params['errors']) > 0 ? '<div style="color:red">' . implode('<br>', $params['errors']) . '</div>' : '') . '<p>名前<input type="text" name="name" value="' . $params['name'] . '"></p><p>メール<input type="email" name="email" value="' . $params['email'] . '"></p><input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '"><button type="submit" name="step" value="confirm">確認</button></form>',
'confirm' => (count($params['errors']) > 0) ? '<form action="index.php" method="post">' . '<div style="color:red">' . implode('<br>', $params['errors']) . '</div>' . '<p>名前<input type="text" name="name" value="' . $params['name'] . '"></p><p>メール<input type="email" name="email" value="' . $params['email'] . '"></p><input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '"><button type="submit" name="step" value="confirm">確認</button></form>' : '<div><p>名前: ' . $params['name'] . '</p><p>メール: ' . $params['email'] . '</p><form action="index.php" method="post"><input type="hidden" name="name" value="' . $params['name'] . '"><input type="hidden" name="email" value="' . $params['email'] . '"><input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '"><button type="submit" name="step" value="complete">送信</button></form></div>',
'complete' => ($params['step'] === 'complete' && count($params['errors']) === 0) ? '<div>送信完了<p>ありがとうございました。</p></div>' : '<form action="index.php" method="post">名前<input type="text" name="name" value="' . $params['name'] . '">メール<input type="email" name="email" value="' . $params['email'] . '"><input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '"><button type="submit" name="step" value="confirm">確認</button></form>'
]
[
// buttonのvalue値に応じて表示するビューを決定
$params['step'] ?? 'input'
]
);
おわりに
PHP8.4以前でも三項演算子や即時実行関数を入れ子にしてワンライナーにできるようですが、入れ子になるため読みにくいものになります。パイプ演算子を使うことで処理の流れ順に記述でき、可読性が上がります。
修正指示をスムーズにする校正ツール「AUN(aun.tools)」を広島を拠点に開発・運営している、株式会社フォノグラムのテックブログです。 エンジニア熱烈❤️🔥募集中です!
Discussion