回答編集履歴
1
sample
answer
CHANGED
@@ -2,4 +2,62 @@
|
|
2
2
|
|
3
3
|
- headerで飛ばす
|
4
4
|
- ワンタイムパスを発行する
|
5
|
-
- 本文の一致をチェックする
|
5
|
+
- 本文の一致をチェックする
|
6
|
+
|
7
|
+
#sample;
|
8
|
+
とりあえずワンタイムパスを利用した二重投稿防止のサンプルつけときます
|
9
|
+
otpカラムがuniqueで二重投稿を防止しています。
|
10
|
+
- テーブル構造
|
11
|
+
```SQL
|
12
|
+
create table XXX(id int not null primary key auto_increment,name varchar(10),comment text,otp varchar(100) not null unique);
|
13
|
+
```
|
14
|
+
|
15
|
+
```PHP
|
16
|
+
<form method="POST" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
|
17
|
+
<input type="text" name="name" placeholder="名前"><br>
|
18
|
+
<input type="text" name="comment" placeholder="コメント">
|
19
|
+
<input type="hidden" name="otp" value="<?PHP print md5(microtime());?>">
|
20
|
+
<input type="submit" value="投稿">
|
21
|
+
</form>
|
22
|
+
|
23
|
+
<?php
|
24
|
+
$otp = filter_input(INPUT_POST,"otp");
|
25
|
+
$name = filter_input(INPUT_POST,"name");
|
26
|
+
$comment = filter_input(INPUT_POST,"comment");
|
27
|
+
try {
|
28
|
+
$pdo = new PDO($dsn, $user, $password);
|
29
|
+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
30
|
+
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
31
|
+
if(!is_null($otp)){
|
32
|
+
$sql = "INSERT INTO XXX (name, comment,otp) VALUES (?,?,?)";
|
33
|
+
$stm = $pdo->prepare($sql);
|
34
|
+
$data=[$name,$comment,$otp];
|
35
|
+
if($stm->execute($data)){
|
36
|
+
echo '追加エラーがありました';
|
37
|
+
}
|
38
|
+
}
|
39
|
+
$sql = "SELECT * FROM XXX ORDER BY id DESC LIMIT 10";
|
40
|
+
$stm = $pdo->query($sql);
|
41
|
+
$result = $stm->fetchAll();
|
42
|
+
foreach ($result as $row) {
|
43
|
+
echo "<div>";
|
44
|
+
echo $row['id'].")";
|
45
|
+
echo htmlspecialchars($row['name']);
|
46
|
+
echo htmlspecialchars($row['comment']);
|
47
|
+
echo "</div>";
|
48
|
+
}
|
49
|
+
} catch (Exception $e) {
|
50
|
+
echo 'エラーがありました。<br>';
|
51
|
+
echo $e->getMessage();
|
52
|
+
}
|
53
|
+
?>
|
54
|
+
</body>
|
55
|
+
```
|
56
|
+
気がついた点
|
57
|
+
- 空のidがhiddenで設定されていますが、なにか意味があるのでしょうか?
|
58
|
+
- 今回例示の処理でinsertが失敗してもidはインクリメントされます
|
59
|
+
- SELECTにWHERE句がなかったのでprepare処理する必要はありません。
|
60
|
+
逆にユーザーから送られてきた任意の条件で絞り込むならprepareで処理してください
|
61
|
+
- $_SERVER["PHP_SELF"]はセキュリティの関係で現在はあまり使われていません
|
62
|
+
- ユーザーから送らてきたデータをHTML上に表示するときにはかならずhtmlspecialcharsなどを通してください
|
63
|
+
- コメントなど文書はnl2br()的な処理も必要かもしれません
|