PHP3でメールフォームを作っています。
メールを送信後、リロード等を行うと同じメール内容が何通を送られてしまいます。
何とかして、制御したいのです。
なんか、いい二重投稿防止方法がありましたらお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

はじめまして、webmonkeyさん。



これは・・、
 
 送信処理を行うphpページを表示(アドレスバーに入力)状態で、リドロー
 (更新や再読込み、アドレスバー上でリターン)された場合
 ※送信処理と完了アナウンスが同phpページに書かれている場合。

の解決という事であれば、2通り浮かびます。

案1)クッキー使用
案2)header()という関数を使用

案2の方が楽でかつ問題もないので、これをおススメします。

・ページとしては3ページ用意
  P1. 入力フォーム(送信ボタンおき)
  P2. 送信実処理およびheader()文のみ※HTMLタグは一切かかずphpコードのみ
  P3. 完了アナウンスページ
・header()の指定は、「header("Location: XX.phtml");」
 ※XX.phtml にP3を指定。(htmlファイルでもいいですし、引数指定も可能)

補足)
  header()を呼び出したページはhistory(履歴)情報に残らないという特徴があります。
  その為、たとえブラウザで「戻る」指定されても、送信実処理ページはもどらず、
  入力フォームに戻ります。
  ※この対処方法は、ただ送信処理と完了アナウンスをページ分けしただけではありません。
  ※入力フォーム上から再「送信」は、この対処方法では回避は無理です。
   ちょっと本題からは外れた操作ですし。
  注)header()呼出前に標準出力があると、header()はうまく動作しません。
    <? ?>以外でHTMLタグ、ただの改行がはいっただけでも駄目なので注意して下さいね。

備考)
 ・案1のクッキー使用では、ブラウザの戻るやリドローに関係なくクッキーは最新
  の情報を保持しているため、1度送信処理したら、「もうこの送信処理はおわったよ」
  と情報をクッキーに書いて、送信処理のphpコード部でこのクッキー値を参照し、
  二重処理を行わないようにできます。
  ※ただし、クッキーのクリアの確立とか色々面倒になると思うので、あまりおススメ
   できないかな・・と。

他にも方法があるかもですが、参考までに。
頑張って下さい。
    • good
    • 0
この回答へのお礼

解答ありがとうございます。
参考になりました。
ご指摘とうり同一ページで作っていました。
案2)の方を利用して修正したいと思います。

お礼日時:2002/01/30 12:33

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QMySQL,PHPのリロードによる二重送信防止

MySQL,PHPについての質問です。

phpmyadmin(テーブル名XXX)を使った
掲示板を作ろうとしているのですが、
リロードの防止ができなくて困っています。
下記の記述途中のコードのどこにどのような関数を置けばいいのかがわかりません。

浅い知識の中で、今まで自分が調べた中では、header('Location:絶対パス',true,303);
を置けばリロード防止できるのではないかと思い、何度も位置を変え記述を変えしているのですが、上手くいきません。

ご回答してくださる方がいれば幸いです。
よろしくお願いします。

index.php

<body> //名前とコメントの投稿フォーム
<form method="POST" action="<?php echo($_SERVER['PHP_SELF']); ?>">
<input type="hidden" name="id">
<input type="text" name="name" placeholder="名前"><br>
<input type="text" name="comment" placeholder="コメント">
<input type="submit" value="投稿">
</form>

<?php

$id = $_POST["id"];
$name = $_POST["name"];
$comment = $_POST["comment"];

try { //SQLに接続
$pdo = new PDO($dsn, $user, $password);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//データベースに追加
$sql = "INSERT INTO XXX (id, name, comment) VALUES (:id, :name, :comment)";

$stm = $pdo->prepare($sql);

$stm->bindValue(':id', $id, PDO::PARAM_INT);
$stm->bindValue(':name', $name, PDO::PARAM_STR);
$stm->bindValue(':comment', $comment, PDO::PARAM_STR);

if ($stm->execute()){
// データベースから全ての投稿を取り出して、ページに表示
$sql = "SELECT * FROM XXX";
$stm = $pdo->prepare($sql);
$stm->execute();
$result = $stm->fetchAll(PDO::FETCH_ASSOC);

foreach ($result as $row) {
echo ($row['name']);
echo ($row['comment']);

";
}
} else {
echo '追加エラーがありました';
};
} catch (Exception $e) {
echo 'エラーがありました。<br>';
echo $e->getMessage();
}
?>


</body>

MySQL,PHPについての質問です。

phpmyadmin(テーブル名XXX)を使った
掲示板を作ろうとしているのですが、
リロードの防止ができなくて困っています。
下記の記述途中のコードのどこにどのような関数を置けばいいのかがわかりません。

浅い知識の中で、今まで自分が調べた中では、header('Location:絶対パス',true,303);
を置けばリロード防止できるのではないかと思い、何度も位置を変え記述を変えしているのですが、上手くいきません。

ご回答してくださる方がいれば幸いです。
よろしくお願いし...続きを読む

Aベストアンサー

通常2重投稿の対策は3種類

・登録後別のheader()のLocationでページに飛ばす(登録完了ページなど)
・microtimeなどからワンタイムパスを作成しhiddenでおくりDBに投入
 おなじパスが来た場合は二重投稿とみなす
・本文が全く同じ内容は二重投稿とみなす

Q掲示板のリロードによる再投稿防止

のためにはどんな手段がありますか?

Aベストアンサー

こんばんわ。

いろいろあるとおもいますが
自分がよく使っているのは
header("Location: ○○.php);
exit;
という方法です。
書込むさいにパラメーターがなければ
ページを表示するだけ、というふうなつくりにしておくと使えます。

あとは、書き込みの時に前回書込まれた内容を取得して
比べてみるとか・・・メンドイですが(;´Д`A ```

以上ご参考までに・・・

Qphpでの二重投稿防止について

お世話になります。

php5にて二重投稿防止のスクリプトを考えておりますが、
なかなか良いものが浮かばず、検索でも見つけられないため質問します。

制作仕様としては、
1つのindex.phpの中に一言コメントを付けて送信するものなのですが、(twitterのような感じ)
更新ボタンを押すと「再送信~」というダイアログが出てしまいます。

別に確認ページや完了ページ等を設ければ、$_SESSIONやheader関数で解決するのですが、
どうしても同一ページ(index.php)内で全てを処理したいのです、何か方法があるのでしょうか?

お手隙の方、ヒントをよろしくお願いいたします。

Aベストアンサー

index.php の中で、POSTデータが有れば処理して index.php へリダイレクトさせ、POSTデータが無ければただ表示だけするようにすれば表示されたページでリロードを行っても「再送信~」は出なくなると思います。

Qこのサイトの二重投稿防止の方法は?

http://www.kirin.co.jp/active/env/mizunomegumi/click.html
上記のURLはキリンのクリック募金ページです。
このページのクリック募金の二重投稿を防止している方法について教えてください。

通常、アンケートなど二重投稿を防止するには、「IP」もしくは「クッキー」の二通りが思いつくのですが、下記のような理由からどちらの制御でもないようなのです。

・初回クッキーの無効設定 → カウントされる
・クリック後にクッキーを削除 → 再カウントされない
(クッキー制御ではない?)
・別のブラウザを変更 → カウントされる
・同一LAN内の別PCからアクセス → カウントされる
(IP制御でもない?)

また、クッキー削除後も「○回目のクリックありがとう」というようにこれまでのトータルクリック数が保存されているのも不思議です。
アンケートでの二重投稿防止などに利用したいのですが、これはどのような制御をしているのでしょうか。その方法もしくはヒントなどご教授いただけませんでしょうか。

他にも下記のサイトに同じようなシステムのリンクがあります。
http://www.dff.jp/(クリック募金サイト)
上記サイト内のコスモ石油・エイブルなど(IPBとカカクコムはクッキー制御のようです)
よろしくお願い致します。

http://www.kirin.co.jp/active/env/mizunomegumi/click.html
上記のURLはキリンのクリック募金ページです。
このページのクリック募金の二重投稿を防止している方法について教えてください。

通常、アンケートなど二重投稿を防止するには、「IP」もしくは「クッキー」の二通りが思いつくのですが、下記のような理由からどちらの制御でもないようなのです。

・初回クッキーの無効設定 → カウントされる
・クリック後にクッキーを削除 → 再カウントされない
(クッキー制御ではない?)
・別のブラ...続きを読む

Aベストアンサー

SharedObjectsは私も考えたのですがフォルダ内にkirin.co.jpのフォルダがないため使ってないのだと思っていました。
C:\Documents and Settings\***\Application Data\Macromedia\Flash Player\#SharedObjects\***\dff.jp
のフォルダを削除したら情報がリセットされましたので#4さんの回答が正解のようです。
ユーザ側で簡単に削除できるのでアンケートには使えませんね。

QPHPで携帯の二重投稿防止の作り方

ども初めまして、匠と申します。よろしくお願いします。

質問は記述の仕方です。(使う関数や考え方)
 

 9/1までに、携帯でも二重投稿防止の投票ホームを作りたいと思っています。

 仕様は

・一人一日一回まで投票できる。

これのみです。

 PCのほうは、クッキーでそのような仕組みを作ったのですが、携帯は携帯個別認識番号なるものを抜き出して、DBに登録しようと考えています。

以下はプログラムです。if文の条件部分がどのように書いたらいいのか迷っています。



//DB登録されている個別認識番号と一致するか

if(送られてきた認識番号がDBに登録されていなかったら){
$sql = "insert into block (`ip`, `time`) values('$ip', '$now_time')";

// データを取り出す
$sql = "SELECT * FROM touhyou ";
$res = mysql_query($sql, $conn) or die("データ抽出エラー");
while( $rec = mysql_fetch_array( $res, MYSQL_ASSOC ) ){
$r_a=$rec['a'];
}
//更新

switch ($post_vote) {
case "aに投票する":
$r_a= $r_a+1;
$sql = "update touhyou set a= $r_a";
mysql_query($sql, $conn);

break;

default :echo"dame";
}


exit;

}

else{
if(現在の時刻と前回訪問から24時間過ぎているを調べる){
認識番号はそのままで時間ののところだけ更新;
投票;
}
else{echo "一日一回しか投票できません";

}

}



 長々と読んでいただきありがとうございます。

是非、よろしくお願いいたします。

ども初めまして、匠と申します。よろしくお願いします。

質問は記述の仕方です。(使う関数や考え方)
 

 9/1までに、携帯でも二重投稿防止の投票ホームを作りたいと思っています。

 仕様は

・一人一日一回まで投票できる。

これのみです。

 PCのほうは、クッキーでそのような仕組みを作ったのですが、携帯は携帯個別認識番号なるものを抜き出して、DBに登録しようと考えています。

以下はプログラムです。if文の条件部分がどのように書いたらいいのか迷っています。



//DB登録され...続きを読む

Aベストアンサー

個別認識番号はすでに取っているとします。($ip)
あと、timeの形式が分からないので適宜修正してください。

$sql = "SELECT * FROM block where ip = '$ip' order by time desc";
$res = mysql_query($sql, $conn);
if ($res and mysql_nom_rows($res)) {
# 未登録
} else {
$rec = mysql_fetch_array($res);
if ($rec['time'] < time()-60*60*24) {
# 24時間以上経っている
} else {
# 投稿してから24時間以内
}

過去の投稿時間を使用しない場合、「REPLACE」を使用したほうがデータ量を抑えられます。


人気Q&Aランキング

おすすめ情報