フォームのリロードで再submitを防ぐ方法

フォームをウェブサイトに設置した時、ユーザーが入力して submit した後、ブラウザをリロードすると再度 submit 処理が走って困る場合があります。

その場合は、プログラムで再 submit を防ぐ処理を入れます。

この記事では、再 submit を防ぐ処理を入れる方法を解説します。

ここでは、フォームの action で飛ぶ先をフォーム設置ページと同ページにするケースに限定します。
例えば、WordPress のプラグインでショートコードでフォームを設置した場合など、このような設計になります。

フォームのリロードで再submitを防ぐ方法

対策としては、PHP のセッションと、フォームの hidden フィールドを使用します。

具体的にコードで説明していきましょう。

初回フォーム表示から submit まで

初回、フォームを表示するときは、最初の if文には入らず、

    $_SESSION["key"] = md5(uniqid().mt_rand());

の部分でセッションキーが生成されます。
そのセッションキーを、フォームの hidden フィールドで送信します。

submit の処理

action の先が同じページなので、再度このスクリプトが実行されます。
その時は POST 処理なので、最初の if文に入ります。
その中でさらに、保存されているセッションキーとフォームから送られてきたキーとを比較し、一致していれば submit処理(my_handle_form_submitted())を実行します。
(セッションに保存されているキー($_SESSION[“key”])を取り出すために、L5のsession_start();で既存のセッションを再開しています。)

同時に、PHP のセッションキーをクリアします。

    unset( $_SESSION["key"] );

submit の処理後のリロード

フォームの処理が終わった後、ユーザーがブラウザでリロードすると、再度このスクリプトが実行されます。
POST 処理なので最初の if文に入りますが、セッションキーはクリアされているため、else の方に入り、

    header('Location: ' . get_permalink() );

が実行されます。
この処理は、同ページにリダイレクトする処理です。
再度このスクリプトが実行されますが、GET アクセスになるので、最初の if文には入らず、

    $_SESSION["key"] = md5(uniqid().mt_rand());

の部分でセッションキーが生成され、フォームが表示される初回に表示した際と同じ流れになります。